mirror of
https://github.com/PhotonVision/photonvision
synced 2026-07-06 03:31:41 +00:00
Add modal and animations while calibration is running (#157)
* Add modal for calibration * Run wpiformat
This commit is contained in:
@@ -143,7 +143,7 @@
|
|||||||
v-for="(value, index) in filteredResolutionList"
|
v-for="(value, index) in filteredResolutionList"
|
||||||
:key="index"
|
:key="index"
|
||||||
>
|
>
|
||||||
<td> {{ value.width }} X {{ value.height }} </td>
|
<td> {{ value.width }} X {{ value.height }}</td>
|
||||||
<td>
|
<td>
|
||||||
{{ isCalibrated(value) ? value.mean.toFixed(2) + "px" : "—" }}
|
{{ isCalibrated(value) ? value.mean.toFixed(2) + "px" : "—" }}
|
||||||
</td>
|
</td>
|
||||||
@@ -218,7 +218,7 @@
|
|||||||
:disabled="checkCancellation"
|
:disabled="checkCancellation"
|
||||||
@click="sendCalibrationFinish"
|
@click="sendCalibrationFinish"
|
||||||
>
|
>
|
||||||
{{ hasEnough ? "End Calibration" : "Cancel Calibration" }}
|
{{ hasEnough ? "Finish Calibration" : "Cancel Calibration" }}
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col>
|
<v-col>
|
||||||
@@ -250,21 +250,72 @@
|
|||||||
cols="12"
|
cols="12"
|
||||||
md="5"
|
md="5"
|
||||||
>
|
>
|
||||||
<CVimage
|
<template>
|
||||||
:address="$store.getters.streamAddress[1]"
|
<CVimage
|
||||||
:disconnected="!$store.state.backendConnected"
|
:address="$store.getters.streamAddress[1]"
|
||||||
scale="100"
|
:disconnected="!$store.state.backendConnected"
|
||||||
style="border-radius: 5px;"
|
scale="100"
|
||||||
/>
|
style="border-radius: 5px;"
|
||||||
|
/>
|
||||||
|
<v-dialog
|
||||||
|
v-model="snack"
|
||||||
|
width="500px"
|
||||||
|
persistent="true"
|
||||||
|
>
|
||||||
|
<v-card
|
||||||
|
color="primary"
|
||||||
|
dark
|
||||||
|
>
|
||||||
|
<v-card-title> Camera Calibration </v-card-title>
|
||||||
|
<div
|
||||||
|
class="ml-3"
|
||||||
|
>
|
||||||
|
<v-col align="center">
|
||||||
|
<template v-if="calibrationInProgress">
|
||||||
|
<v-progress-circular
|
||||||
|
indeterminate
|
||||||
|
:size="70"
|
||||||
|
:width="8"
|
||||||
|
color="accent"
|
||||||
|
/>
|
||||||
|
<v-card-text>Camera is being calibrated. This process make take several minutes...</v-card-text>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="!calibrationFailed">
|
||||||
|
<v-icon
|
||||||
|
color="green"
|
||||||
|
size="70"
|
||||||
|
>
|
||||||
|
mdi-check-bold
|
||||||
|
</v-icon>
|
||||||
|
<v-card-text>Camera has been successfully calibrated at {{ stringResolutionList[selectedFilteredResIndex] }}!</v-card-text>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<v-icon
|
||||||
|
color="red"
|
||||||
|
size="70"
|
||||||
|
>
|
||||||
|
mdi-close
|
||||||
|
</v-icon>
|
||||||
|
<v-card-text>Camera calibration failed! Make sure that the photos are taken such that the rainbow grid circles align with the corners of the chessboard, and try again. More information is available in the program logs.</v-card-text>
|
||||||
|
</template>
|
||||||
|
</v-col>
|
||||||
|
</div>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn
|
||||||
|
v-if="!calibrationInProgress"
|
||||||
|
color="white"
|
||||||
|
text
|
||||||
|
@click="closeDialog"
|
||||||
|
>
|
||||||
|
OK
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-snackbar
|
|
||||||
v-model="snack"
|
|
||||||
top
|
|
||||||
:color="snackbar.color"
|
|
||||||
>
|
|
||||||
<span>{{ snackbar.text }}</span>
|
|
||||||
</v-snackbar>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -278,7 +329,7 @@ import TooltippedLabel from "../components/common/cv-tooltipped-label";
|
|||||||
export default {
|
export default {
|
||||||
name: 'Cameras',
|
name: 'Cameras',
|
||||||
components: {
|
components: {
|
||||||
TooltippedLabel,
|
TooltippedLabel,
|
||||||
CVselect,
|
CVselect,
|
||||||
CVnumberinput,
|
CVnumberinput,
|
||||||
CVslider,
|
CVslider,
|
||||||
@@ -286,11 +337,9 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
snackbar: {
|
|
||||||
color: "success",
|
|
||||||
text: ""
|
|
||||||
},
|
|
||||||
snack: false,
|
snack: false,
|
||||||
|
calibrationInProgress: false,
|
||||||
|
calibrationFailed: false,
|
||||||
filteredVideomodeIndex: undefined,
|
filteredVideomodeIndex: undefined,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -325,7 +374,7 @@ export default {
|
|||||||
if (!filtered.some(e => e.width === it.width && e.height === it.height)) {
|
if (!filtered.some(e => e.width === it.width && e.height === it.height)) {
|
||||||
it['index'] = i;
|
it['index'] = i;
|
||||||
const calib = this.getCalibrationCoeffs(it);
|
const calib = this.getCalibrationCoeffs(it);
|
||||||
if(calib != null) {
|
if (calib != null) {
|
||||||
it['standardDeviation'] = calib.standardDeviation;
|
it['standardDeviation'] = calib.standardDeviation;
|
||||||
it['mean'] = calib.perViewErrors.reduce((a, b) => a + b) / calib.perViewErrors.length;
|
it['mean'] = calib.perViewErrors.reduce((a, b) => a + b) / calib.perViewErrors.length;
|
||||||
}
|
}
|
||||||
@@ -421,12 +470,16 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
closeDialog() {
|
||||||
|
this.snack = false;
|
||||||
|
this.calibrationInProgress = false;
|
||||||
|
this.calibrationFailed = false;
|
||||||
|
},
|
||||||
getCalibrationCoeffs(resolution) {
|
getCalibrationCoeffs(resolution) {
|
||||||
const calList = this.$store.getters.calibrationList;
|
const calList = this.$store.getters.calibrationList;
|
||||||
let ret = null;
|
let ret = null;
|
||||||
calList.forEach(cal => {
|
calList.forEach(cal => {
|
||||||
if(cal.width === resolution.width && cal.height === resolution.height) {
|
if (cal.width === resolution.width && cal.height === resolution.height) {
|
||||||
ret = cal
|
ret = cal
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -475,34 +528,19 @@ export default {
|
|||||||
sendCalibrationFinish() {
|
sendCalibrationFinish() {
|
||||||
console.log("finishing calibration for index " + this.$store.getters.currentCameraIndex);
|
console.log("finishing calibration for index " + this.$store.getters.currentCameraIndex);
|
||||||
|
|
||||||
this.snackbar.text = "Calibrating...";
|
|
||||||
this.snackbar.color = "secondary";
|
|
||||||
this.snack = true;
|
this.snack = true;
|
||||||
|
this.calibrationInProgress = true;
|
||||||
|
|
||||||
this.axios.post("http://" + this.$address + "/api/settings/endCalibration", this.$store.getters.currentCameraIndex)
|
this.axios.post("http://" + this.$address + "/api/settings/endCalibration", this.$store.getters.currentCameraIndex)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
this.snackbar = {
|
this.calibrationInProgress = false;
|
||||||
color: "success",
|
} else {
|
||||||
text: "Calibration successful! \n" +
|
this.calibrationFailed = true;
|
||||||
"Standard deviation: " + response.data.toFixed(5)
|
}
|
||||||
};
|
|
||||||
this.snack = true;
|
|
||||||
}
|
}
|
||||||
else {
|
).catch(() => {
|
||||||
this.snackbar = {
|
this.calibrationFailed = true;
|
||||||
color: "error",
|
|
||||||
text: "Calibration Failed!"
|
|
||||||
};
|
|
||||||
this.snack = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
).catch(() => {
|
|
||||||
this.snackbar = {
|
|
||||||
color: "error",
|
|
||||||
text: "Calibration Failed!"
|
|
||||||
};
|
|
||||||
this.snack = true;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -510,18 +548,19 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.v-data-table {
|
.v-data-table {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.v-data-table th {
|
|
||||||
background-color: #006492 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v-data-table th,td {
|
.v-data-table th {
|
||||||
font-size: 1rem !important;
|
background-color: #006492 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.v-data-table th, td {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -162,6 +162,7 @@ public class RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void onCalibrationEnd(Context ctx) {
|
public static void onCalibrationEnd(Context ctx) {
|
||||||
|
logger.info("Calibrating camera! This will take a long time...");
|
||||||
var index = Integer.parseInt(ctx.body());
|
var index = Integer.parseInt(ctx.body());
|
||||||
var calData = VisionModuleManager.getInstance().getModule(index).endCalibration();
|
var calData = VisionModuleManager.getInstance().getModule(index).endCalibration();
|
||||||
if (calData == null) {
|
if (calData == null) {
|
||||||
@@ -171,6 +172,7 @@ public class RequestHandler {
|
|||||||
|
|
||||||
ctx.result(String.valueOf(calData.standardDeviation));
|
ctx.result(String.valueOf(calData.standardDeviation));
|
||||||
ctx.status(200);
|
ctx.status(200);
|
||||||
|
logger.info("Camera calibrated!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void restartDevice(Context ctx) {
|
public static void restartDevice(Context ctx) {
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ public class Calibrate3dPipeline
|
|||||||
|
|
||||||
private int minSnapshots;
|
private int minSnapshots;
|
||||||
|
|
||||||
|
private boolean calibrating = false;
|
||||||
|
|
||||||
public Calibrate3dPipeline() {
|
public Calibrate3dPipeline() {
|
||||||
this(25);
|
this(25);
|
||||||
}
|
}
|
||||||
@@ -89,6 +91,11 @@ public class Calibrate3dPipeline
|
|||||||
// Set the pipe parameters
|
// Set the pipe parameters
|
||||||
setPipeParams(frame.frameStaticProperties, settings);
|
setPipeParams(frame.frameStaticProperties, settings);
|
||||||
|
|
||||||
|
if (this.calibrating) {
|
||||||
|
return new CVPipelineResult(
|
||||||
|
0, null, new Frame(new CVMat(frame.image.getMat()), frame.frameStaticProperties));
|
||||||
|
}
|
||||||
|
|
||||||
long sumPipeNanosElapsed = 0L;
|
long sumPipeNanosElapsed = 0L;
|
||||||
|
|
||||||
// Check if the frame has chessboard corners
|
// Check if the frame has chessboard corners
|
||||||
@@ -131,10 +138,14 @@ public class Calibrate3dPipeline
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.calibrating = true;
|
||||||
|
|
||||||
/*Pass the board corners to the pipe, which will check again to see if all boards are valid
|
/*Pass the board corners to the pipe, which will check again to see if all boards are valid
|
||||||
and returns the corresponding image and object points*/
|
and returns the corresponding image and object points*/
|
||||||
calibrationOutput = calibrate3dPipe.run(foundCornersList);
|
calibrationOutput = calibrate3dPipe.run(foundCornersList);
|
||||||
|
|
||||||
|
this.calibrating = false;
|
||||||
|
|
||||||
return calibrationOutput.output;
|
return calibrationOutput.output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user