Add calibration decimate dropdown (#739)

* Increase resized size to 640

* Add calibration decimation dropdown

* Update Calibrate3dPipeTest.java

* Only allow decimation down to >=320x240

* Update CamerasView.vue
This commit is contained in:
Matt
2023-01-14 20:23:14 -05:00
committed by GitHub
parent 357d8a518a
commit d9f99f9c9b
5 changed files with 86 additions and 30 deletions

View File

@@ -72,6 +72,14 @@
:disabled="isCalibrating"
tooltip="Resolution to calibrate at (you will have to calibrate every resolution you use 3D mode on)"
/>
<CVselect
v-model="streamingFrameDivisor"
name="Decimation"
tooltip="Resolution to which camera frames are downscaled for detection. Calibration still uses full-res"
:list="calibrationDivisors"
select-cols="7"
@rollback="e => rollback('streamingFrameDivisor', e)"
/>
<CVselect
v-model="boardType"
name="Board Type"
@@ -397,6 +405,7 @@ export default {
calibrationFailed: false,
filteredVideomodeIndex: 0,
settingsValid: true,
unfilteredStreamDivisors: [1, 2, 4],
}
},
computed: {
@@ -430,6 +439,22 @@ export default {
}
},
calibrationDivisors: {
get() {
return this.unfilteredStreamDivisors.filter(item => {
var res = this.stringResolutionList[this.selectedFilteredResIndex].split(" X ").map(it => parseInt(it));
console.log(res);
console.log(item);
// Realistically, we need more than 320x240, but lower than this is
// basically unusable. For now, don't allow decimations that take us
// below that
const ret = ((res[0] / item) >= 300 && (res[1] / item) >= 220) || (item === 1);
console.log(ret);
return ret;
})
}
},
// Makes sure there's only one entry per resolution
filteredResolutionList: {
get() {
@@ -466,6 +491,17 @@ export default {
this.$store.commit('cameraSettings', value);
}
},
streamingFrameDivisor: {
get() {
return this.$store.getters.currentPipelineSettings.streamingFrameDivisor;
},
set(val) {
this.$store.commit("mutatePipeline", {"streamingFrameDivisor": val});
this.handlePipelineUpdate("streamingFrameDivisor", val);
}
},
boardType: {
get() {
return this.calibrationData.boardType

View File

@@ -17,7 +17,6 @@
package org.photonvision.vision.pipe.impl;
import java.util.Objects;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.opencv.calib3d.Calib3d;
@@ -25,6 +24,7 @@ import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import org.photonvision.common.logging.LogGroup;
import org.photonvision.common.logging.Logger;
import org.photonvision.vision.frame.FrameDivisor;
import org.photonvision.vision.pipe.CVPipe;
import org.photonvision.vision.pipeline.UICalibrationData;
@@ -39,10 +39,6 @@ public class FindBoardCornersPipe
Size imageSize;
Size patternSize;
// Tune to taste for a reasonable tradeoff between making
// the findCorners portion work hard, versus the subpixel refinement work hard.
final int FIND_CORNERS_WIDTH_PX = 320;
// Configure the optimizations used while using openCV's find corners algorithm
// Since we return results in real-time, we want ensure it goes as fast as possible
// and fails as fast as possible.
@@ -125,17 +121,13 @@ public class FindBoardCornersPipe
/**
* Figures out how much a frame or point cloud must be scaled down by to match the desired size at
* which to run FindCorners
* which to run FindCorners. Should usually be > 1.
*
* @param inFrame
* @return
*/
private double getFindCornersScaleFactor(Mat inFrame) {
if (inFrame.width() > FIND_CORNERS_WIDTH_PX) {
return ((double) FIND_CORNERS_WIDTH_PX) / inFrame.width();
} else {
return 1.0;
}
return 1.0 / params.divisor.value;
}
/**
@@ -174,9 +166,10 @@ public class FindBoardCornersPipe
* findBoardCorners
* @return the size to scale the input mat to
*/
private Size getFindCornersImgSize(Mat inFrame) {
var findcorners_height = Math.round(inFrame.height() * getFindCornersScaleFactor(inFrame));
return new Size(FIND_CORNERS_WIDTH_PX, findcorners_height);
private Size getFindCornersImgSize(Mat in) {
int width = in.cols() / params.divisor.value;
int height = in.rows() / params.divisor.value;
return new Size(width, height);
}
/**
@@ -295,29 +288,48 @@ public class FindBoardCornersPipe
private final int boardWidth;
private final UICalibrationData.BoardType type;
private final double gridSize;
private final FrameDivisor divisor;
public FindCornersPipeParams(
int boardHeight, int boardWidth, UICalibrationData.BoardType type, double gridSize) {
int boardHeight,
int boardWidth,
UICalibrationData.BoardType type,
double gridSize,
FrameDivisor divisor) {
this.boardHeight = boardHeight;
this.boardWidth = boardWidth;
this.type = type;
this.gridSize = gridSize; // mm
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FindCornersPipeParams that = (FindCornersPipeParams) o;
return boardHeight == that.boardHeight
&& boardWidth == that.boardWidth
&& Double.compare(that.gridSize, gridSize) == 0
&& type == that.type;
this.divisor = divisor;
}
@Override
public int hashCode() {
return Objects.hash(boardHeight, boardWidth, type, gridSize);
final int prime = 31;
int result = 1;
result = prime * result + boardHeight;
result = prime * result + boardWidth;
result = prime * result + ((type == null) ? 0 : type.hashCode());
long temp;
temp = Double.doubleToLongBits(gridSize);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((divisor == null) ? 0 : divisor.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
FindCornersPipeParams other = (FindCornersPipeParams) obj;
if (boardHeight != other.boardHeight) return false;
if (boardWidth != other.boardWidth) return false;
if (type != other.type) return false;
if (Double.doubleToLongBits(gridSize) != Double.doubleToLongBits(other.gridSize))
return false;
if (divisor != other.divisor) return false;
return true;
}
}
}

View File

@@ -87,7 +87,11 @@ public class Calibrate3dPipeline
protected void setPipeParamsImpl() {
FindBoardCornersPipe.FindCornersPipeParams findCornersPipeParams =
new FindBoardCornersPipe.FindCornersPipeParams(
settings.boardHeight, settings.boardWidth, settings.boardType, settings.gridSize);
settings.boardHeight,
settings.boardWidth,
settings.boardType,
settings.gridSize,
settings.streamingFrameDivisor);
findBoardCornersPipe.setParams(findCornersPipeParams);
Calibrate3dPipe.CalibratePipeParams calibratePipeParams =
@@ -105,7 +109,7 @@ public class Calibrate3dPipeline
protected CVPipelineResult process(Frame frame, Calibration3dPipelineSettings settings) {
Mat inputColorMat = frame.colorImage.getMat();
if (this.calibrating) {
if (this.calibrating || inputColorMat.empty()) {
return new CVPipelineResult(0, 0, null, frame);
}

View File

@@ -19,6 +19,7 @@ package org.photonvision.vision.pipeline;
import edu.wpi.first.math.util.Units;
import org.opencv.core.Size;
import org.photonvision.vision.frame.FrameDivisor;
public class Calibration3dPipelineSettings extends AdvancedPipelineSettings {
public int boardHeight = 8;
@@ -33,5 +34,6 @@ public class Calibration3dPipelineSettings extends AdvancedPipelineSettings {
this.cameraAutoExposure = true;
this.inputShouldShow = true;
this.outputShouldShow = true;
this.streamingFrameDivisor = FrameDivisor.HALF;
}
}

View File

@@ -37,6 +37,7 @@ import org.photonvision.common.util.TestUtils;
import org.photonvision.vision.calibration.CameraCalibrationCoefficients;
import org.photonvision.vision.camera.QuirkyCamera;
import org.photonvision.vision.frame.Frame;
import org.photonvision.vision.frame.FrameDivisor;
import org.photonvision.vision.frame.FrameStaticProperties;
import org.photonvision.vision.frame.FrameThresholdType;
import org.photonvision.vision.opencv.CVMat;
@@ -62,7 +63,7 @@ public class Calibrate3dPipeTest {
FindBoardCornersPipe findBoardCornersPipe = new FindBoardCornersPipe();
findBoardCornersPipe.setParams(
new FindBoardCornersPipe.FindCornersPipeParams(
11, 4, UICalibrationData.BoardType.DOTBOARD, 15));
11, 4, UICalibrationData.BoardType.DOTBOARD, 15, FrameDivisor.NONE));
List<Triple<Size, Mat, Mat>> foundCornersList = new ArrayList<>();
@@ -264,6 +265,7 @@ public class Calibrate3dPipeTest {
calibration3dPipeline.getSettings().boardHeight = (int) Math.round(boardDim.height);
calibration3dPipeline.getSettings().boardWidth = (int) Math.round(boardDim.width);
calibration3dPipeline.getSettings().gridSize = boardGridSize_m;
calibration3dPipeline.getSettings().streamingFrameDivisor = FrameDivisor.NONE;
for (var file : directoryListing) {
if (file.isFile()) {