Add camera calibration steps into refactored calibration wizard.

This commit is contained in:
Julian Stirling 2025-10-22 22:45:19 +01:00
parent 8f1253ec02
commit 0ebc507eff
10 changed files with 186 additions and 32 deletions

View file

@ -86,6 +86,11 @@ class SimulatedCamera(BaseCamera):
self.generate_blobs()
self.generate_canvas()
@lt.thing_property
def calibration_required(self) -> bool:
"""Whether the camera needs calibrating."""
return not self.background_detector_status.ready
def validate_inputs(self) -> None:
"""Validate the inputs passed to the simulation, and raises an error if invalid.
@ -367,6 +372,22 @@ class SimulatedCamera(BaseCamera):
LOGGER.warning(f"Simulation camera camera doesn't respect {stream_name=}")
return Image.fromarray(self.generate_frame())
@lt.thing_action
def full_auto_calibrate(self, portal: lt.deps.BlockingPortal) -> None:
"""Perform a full auto-calibration.
For the simulation microscope the process is:
* ``remove_sample``
* ``set_background``
* ``load_sample``
"""
self.remove_sample()
time.sleep(0.2)
self.set_background(portal)
time.sleep(0.2)
self.load_sample()
@lt.thing_action
def remove_sample(self) -> None:
"""Show the simulated background with no sample."""
@ -381,6 +402,15 @@ class SimulatedCamera(BaseCamera):
raise RuntimeError("Sample is already in place.")
self._show_sample = True
@lt.thing_property
def primary_calibration_actions(self) -> list[ActionButton]:
"""The calibration actions for both calibration wizard and settings panel."""
return [
action_button_for(
self.full_auto_calibrate, submit_label="Full Auto Calibrate"
),
]
@lt.thing_property
def secondary_calibration_actions(self) -> list[ActionButton]:
"""The calibration actions that appear only in settings panel."""

View file

@ -22,6 +22,8 @@
<script>
import singleStepTask from "./calibrationWizardComponents/singleStepTask.vue";
import welcomeStep from "./calibrationWizardComponents/welcomeStep.vue";
import cameraCalibrationTask from "./calibrationWizardComponents/cameraCalibrationTask.vue";
import finalStep from "./calibrationWizardComponents/finalStep.vue";
export default {
name: "calibrationWizard",
@ -60,6 +62,8 @@ export default {
this.calibrateableThings = thingsToCheck.filter(name => this.thingAvailable(name));
this.tasks = [
{component: singleStepTask, props: {stepComponent: welcomeStep}},
{component: cameraCalibrationTask},
{component: singleStepTask, props: {stepComponent: finalStep}},
]
},
@ -98,7 +102,7 @@ export default {
},
show_if_needed: async function() {
// Check if the camera and stage are calibrated, if they can be
// Check if the calibration modal is needed, and only show it if it is.
let needed = await this.check_if_needed()
// Check if this calibration wizard can actually do anything useful
@ -117,7 +121,6 @@ export default {
this.show();
},
show: function() {
// Show the modal element
var el = this.$refs["calibrationModalEl"];

View file

@ -3,18 +3,7 @@
structure
-->
<div v-show="stepValue == 0">
<p>
<b
>Some important microscope calibration data is currently missing.</b
>
</p>
<p>
Your microscope will still function, however some functionality will
be limited, and image quality will likely suffer.
</p>
<p>
<b>Click Next to begin microscope calibration.</b>
</p>
</div>
<div v-show="stepValue == 1">
@ -28,16 +17,7 @@
</p>
</div>
<div v-else>
<p>
<b
>Follow the important steps below before starting lens-shading
calibration!</b
>
</p>
<ul class="uk-list uk-list-bullet">
<li>Remove any samples from your microscope</li>
<li>Ensure your illumination is on and properly fixed in place</li>
</ul>
<miniStreamDisplay
v-if="stepValue == 1"

View file

@ -11,6 +11,7 @@ Tasks can be divided into multiple steps.
-->
<template>
<div>
<h3 v-if="title">{{ title }}</h3>
<component
v-if="currentStep"
:is="currentStep.component"
@ -43,6 +44,10 @@ export default {
name: "calibrationWizardTask",
props: {
title: {
type: String,
default: null
},
first: Boolean,
final: Boolean,
startOnLast: {
@ -61,10 +66,6 @@ export default {
};
},
mounted() {
console.log("Steps received:", this.steps);
},
computed: {
currentStep() {
return this.steps[this.stepIndex] || null;

View file

@ -0,0 +1,20 @@
<template>
<div>
<p>
<b>
Before starting camera calibration:
</b>
</p>
<ul class="uk-list uk-list-bullet">
<li>Remove any samples from your microscope</li>
<li>Ensure your illumination is on, well focussed, and centred.</li>
</ul>
</div>
</template>
<script>
export default {
name: "camCalibrationExplanation"
}
</script>

View file

@ -0,0 +1,34 @@
<template>
<stepTemplateWithStream>
<p>
<b>
<p>Once you're ready, click auto-calibrate.</p>
<cameraCalibrationSettings
:show-extra-settings="false"
:camera-uri="cameraUri"
></cameraCalibrationSettings>
</b>
</p>
</stepTemplateWithStream>
</template>
<script>
import stepTemplateWithStream from "../stepTemplateWithStream.vue"
import cameraCalibrationSettings from "../../../tabContentComponents/settingsComponents/cameraSettingsComponents/cameraCalibrationSettings.vue";
export default {
name: "cameraMainCalibrationStep",
components: {
stepTemplateWithStream,
cameraCalibrationSettings
},
computed: {
cameraUri: function() {
return `${this.$store.getters.baseUri}/camera/`;
}
}
}
</script>

View file

@ -0,0 +1,41 @@
<template>
<calibrationWizardTask
title="Camera Calibration"
:first="first"
:final="final"
:startOnLast="startOnLast"
:steps="steps"
@next="$emit('next')"
@back="$emit('back')"
/>
</template>
<script>
import calibrationWizardTask from "./calibrationWizardTask.vue";
import camCalibrationExplanation from "./cameraCalibrationSteps/camCalibrationExplanation.vue";
import cameraMainCalibrationStep from "./cameraCalibrationSteps/cameraMainCalibrationStep.vue";
export default {
name: "cameraCalibrationTask",
components: {calibrationWizardTask},
props: {
// Standard calibrationWizardTask props below:
first: Boolean,
final: Boolean,
startOnLast: {
type: Boolean,
default: false
}
},
data: function() {
return {
steps: [
{component: camCalibrationExplanation},
{component: cameraMainCalibrationStep},
]
};
}
}
</script>

View file

@ -0,0 +1,17 @@
<template>
<div>
<p>
<b>Calibration complete</b>
</p>
<p>
Click Finish to return to your microscope.
</p>
</div>
</template>
<script>
export default {
name: "finalStep"
}
</script>

View file

@ -1,5 +1,6 @@
<template>
<calibrationWizardTask
:title="title"
:first="first"
:final="final"
:startOnLast="startOnLast"
@ -24,6 +25,10 @@ export default {
default: () => ({})
},
// Standard calibrationWizardTask props below:
title: {
type: String,
default: null
},
first: Boolean,
final: Boolean,
startOnLast: {
@ -39,9 +44,5 @@ export default {
]
};
},
mounted(){
console.log(this.stepComponent);
}
}
</script>

View file

@ -0,0 +1,27 @@
<template>
<div>
<slot></slot>
<miniStreamDisplay class="mini-preview" />
</div>
</template>
<script>
import miniStreamDisplay from "../../genericComponents/miniStreamDisplay.vue";
export default {
name: "stepTemplateWithStream",
components: {
miniStreamDisplay
}
}
</script>
<style scoped>
.mini-preview {
width: 75%;
margin-left: auto;
margin-right: auto;
}
</style>