Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/source/docs/calibration/calibration.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ We'll next select a resolution to calibrate and populate our pattern spacing, ma
If you have a [calib.io](https://calib.io/) CharuCo Target you will have to enter the paramaters of your target. For example if your target says "9x12 | Checker Size: 30 mm | Marker Size: 22 mm | Dictionary: AruCo DICT 5x5", you would have to set the board type to Dict_5x5_1000, the pattern spacing to 1.1811 in (30 mm converted to inches), the marker size 0.866142 in (22 mm converted to inches), the board width to 12 and the board height to 9. If you chose the wrong tag family the board wont be detected during calibration. If you swap the width and height your calibration will have a very high error.
:::

### 4. Take at calibration images from various angles.
::{note}
Using the `Snapshot Loop` feature can help speed up the image capture process. This feature will continuously take snapshots at a set interval until the user stops it. This is useful for capturing images from different angles quickly without having to manually click the snapshot button each time.
:::

### 4. Take calibration images from various angles.

Now, we'll capture images of our board from various angles. It's important to check that the board overlay matches the board in your image. The further the overdrawn points are from the true position of the chessboard corners, the less accurate the final calibration will be. We'll want to capture enough images to cover the whole camera's FOV (with a minimum of 12). Once we've got our images, we'll click "Finish calibration" and wait for the calibration process to complete. If all goes well, the mean error and FOVs will be shown in the table on the right. The FOV should be close to the camera's specified FOV (usually found in a datasheet) usually within + or - 10 degrees. The mean error should also be low, usually less than 1 pixel.

Expand Down
18 changes: 18 additions & 0 deletions photon-client/src/components/cameras/CameraCalibrationCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ const calibCanceled = ref(false);
const calibSuccess = ref<boolean | undefined>(undefined);
const calibEndpointFail = ref(false);
const endCalibration = () => {
useCameraSettingsStore().stopCalibrationSnapshotLoop();
calibSuccess.value = undefined;
calibEndpointFail.value = false;

Expand Down Expand Up @@ -505,6 +506,7 @@ const setSelectedVideoFormat = (format: VideoFormat) => {
<v-btn
size="small"
block
v-if="isCalibrating"
:variant="theme.global.name.value === 'LightTheme' ? 'elevated' : 'outlined'"
:color="useStateStore().calibrationData.hasEnoughImages ? 'buttonActive' : 'error'"
:disabled="!isCalibrating || !settingsValid"
Expand All @@ -517,6 +519,22 @@ const setSelectedVideoFormat = (format: VideoFormat) => {
useStateStore().calibrationData.hasEnoughImages ? "Finish Calibration" : "Cancel Calibration"
}}</span>
</v-btn>
<v-btn
size="small"
block
v-if="!isCalibrating"
color="buttonActive"
:variant="theme.global.name.value === 'LightTheme' ? 'elevated' : 'outlined'"
:disabled="!settingsValid"
tooltip="Automatically take calibration snapshots in a loop until calibration is ended"
@click="
startCalibration();
useCameraSettingsStore().startCalibrationSnapshotLoop();
"
>
<v-icon start class="calib-btn-icon" size="large"> mdi-autorenew </v-icon>
<span class="calib-btn-label"> Start Snapshot Loop </span>
</v-btn>
</v-col>
</div>
</v-card-text>
Expand Down
26 changes: 26 additions & 0 deletions photon-client/src/stores/settings/CameraSettingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,32 @@ export const useCameraSettingsStore = defineStore("cameraSettings", {
};
useStateStore().websocket?.send(payload, true);
},

/**
* Start repeatedly calling takeCalibrationSnapshot every intervalMs milliseconds.
* No-op if already running. Call stopCalibrationSnapshotLoop() to stop.
*
* @param intervalMs interval in milliseconds between snapshots (default 1000)
* @param cameraUniqueName camera to snapshot (captured when the loop starts)
*/
startCalibrationSnapshotLoop(intervalMs = 500, cameraUniqueName: string = useStateStore().currentCameraUniqueName) {
// store the interval id on the store instance (avoid changing state shape)
if ((this as any)._calibrationSnapshotInterval != null) return;
// take one immediately then schedule
this.takeCalibrationSnapshot(cameraUniqueName);
(this as any)._calibrationSnapshotInterval = window.setInterval(() => {
this.takeCalibrationSnapshot(cameraUniqueName);
}, intervalMs);
},

/**
* Stop a running calibration snapshot loop started with startCalibrationSnapshotLoop().
*/
stopCalibrationSnapshotLoop() {
if ((this as any)._calibrationSnapshotInterval == null) return;
clearInterval((this as any)._calibrationSnapshotInterval);
(this as any)._calibrationSnapshotInterval = null;
},
/**
* Save a snapshot of the input frame of the camera.
*
Expand Down
Loading