mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-19 00:41:41 +00:00
Disallow low-resolution calibration (#2438)
This commit is contained in:
@@ -7,7 +7,7 @@ In order to detect AprilTags and use 3D mode, your camera must be calibrated at
|
||||
To calibrate a camera, images of a ChArUco board (or chessboard) are taken. By comparing where the grid corners should be in object space (for example, a corner once every inch in an 8x6 grid) with where they appear in the camera image, we can find a least-squares estimate for intrinsic camera properties like focal lengths, center point, and distortion coefficients. For more on camera calibration, please review the [OpenCV documentation](https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html).
|
||||
|
||||
:::{warning}
|
||||
While any resolution can be calibrated, higher resolutions may be too performance-intensive for some coprocessors to handle. Therefore, we recommend experimenting to see what works best for your coprocessor.
|
||||
PhotonVision supports many resolution configuration options, with only a minimum of 640x480 required. However, higher resolutions may be too performance-intensive for some coprocessors to handle. Therefore, we recommend experimenting to see what works best for your coprocessor.
|
||||
:::
|
||||
|
||||
:::{note}
|
||||
|
||||
@@ -38,6 +38,11 @@ const getUniqueVideoFormatsByResolution = (): VideoFormat[] => {
|
||||
|
||||
if (!skip) {
|
||||
const calib = useCameraSettingsStore().getCalibrationCoeffs(format.resolution);
|
||||
|
||||
// minPixelCount is the multiplied area of a 640x480 (the minimum for proper calibration) resolution
|
||||
const minPixelCount = 640 * 480;
|
||||
const resArea = format.resolution.width * format.resolution.height;
|
||||
|
||||
if (calib !== undefined) {
|
||||
// Mean overall reprojection error
|
||||
// Calculated as average of each observation's mean error
|
||||
@@ -60,7 +65,10 @@ const getUniqueVideoFormatsByResolution = (): VideoFormat[] => {
|
||||
) *
|
||||
(180 / Math.PI);
|
||||
}
|
||||
uniqueResolutions.push(format);
|
||||
|
||||
if (resArea >= minPixelCount) {
|
||||
uniqueResolutions.push(format);
|
||||
}
|
||||
}
|
||||
});
|
||||
uniqueResolutions.sort(
|
||||
@@ -86,12 +94,19 @@ const uniqueVideoResolutionString = ref("");
|
||||
// Use a watchEffect so the value is populated/reacts when the stores become available or update.
|
||||
// This avoids trying to index into an array that may be empty during page reload.
|
||||
watchEffect(() => {
|
||||
const currentIndex = useCameraSettingsStore().currentVideoFormat.index ?? 0;
|
||||
useStateStore().calibrationData.videoFormatIndex = currentIndex;
|
||||
const names = useCameraSettingsStore().currentCameraSettings.validVideoFormats.map((f) =>
|
||||
getResolutionString(f.resolution)
|
||||
);
|
||||
uniqueVideoResolutionString.value = names[currentIndex] ?? names[0] ?? "";
|
||||
const currentFormatIndex = useCameraSettingsStore().currentVideoFormat.index ?? 0;
|
||||
// Checks if the current resolution is present in the list of valid formats, if not defaults to the last index (which is usually the highest resolution)
|
||||
const currentIndex =
|
||||
getUniqueVideoResolutionStrings()
|
||||
.map((x) => x.name)
|
||||
.find((n) => n === names[currentFormatIndex]) !== undefined
|
||||
? currentFormatIndex
|
||||
: names.length - 1;
|
||||
useStateStore().calibrationData.videoFormatIndex = currentIndex;
|
||||
uniqueVideoResolutionString.value = names[currentIndex] ?? "";
|
||||
});
|
||||
const squareSizeIn = ref(1);
|
||||
const markerSizeIn = ref(0.75);
|
||||
|
||||
Reference in New Issue
Block a user