Get new background detect running in simulation mode.

This commit is contained in:
Julian Stirling 2025-07-18 21:21:25 +01:00
parent fe1b84a922
commit eed3c44804
3 changed files with 16 additions and 21 deletions

View file

@ -158,23 +158,23 @@ class ColourChannelDetectLUV(BackgroundDetectAlgorithm):
def background_mask(self, image: np.ndarray) -> np.ndarray: def background_mask(self, image: np.ndarray) -> np.ndarray:
"""Calculate a binary image, showing whether each pixel is background. """Calculate a binary image, showing whether each pixel is background.
True is background.
The image should be in LUV format, the output will be binary with the The image should be in LUV format, the output will be binary with the
same shape in the first two dimensions. same shape in the first two dimensions.
# human-intuitive way
""" """
d = self.background_data d = self.background_data
if not d: if not d:
raise RuntimeError( raise RuntimeError(
"Background is not set: you need to calibrate background detection." "Background is not set: you need to calibrate background detection."
) )
print(d)
# Only use the U and V channels of as brightness (L) often changes as the # Only use the U and V channels of as brightness (L) often changes as the
# height of the sample changes. # height of the sample changes.
return np.all( return np.all(
np.abs(image[:, :, 1:] - np.array(d.means[1:])[np.newaxis, np.newaxis, :]) np.abs(image[:, :, 1:] - np.array(d.means[1:])[np.newaxis, np.newaxis, :])
< np.array(d.standard_deviations[1:])[np.newaxis, np.newaxis, :] < np.array(d.standard_deviations[1:])[np.newaxis, np.newaxis, :]
* self.channel_tolerance, * self.settings.channel_tolerance,
axis=2, axis=2,
) )
@ -189,6 +189,9 @@ class ColourChannelDetectLUV(BackgroundDetectAlgorithm):
""" """
image_luv = cv2.cvtColor(image, cv2.COLOR_RGB2LUV) image_luv = cv2.cvtColor(image, cv2.COLOR_RGB2LUV)
mask = self.background_mask(image_luv) mask = self.background_mask(image_luv)
print(np.count_nonzero(mask))
print(np.prod(mask.shape))
print((1 - np.count_nonzero(mask) / np.prod(mask.shape)) * 100)
return (1 - np.count_nonzero(mask) / np.prod(mask.shape)) * 100 return (1 - np.count_nonzero(mask) / np.prod(mask.shape)) * 100
def image_is_sample(self, image: np.ndarray) -> tuple[bool, str]: def image_is_sample(self, image: np.ndarray) -> tuple[bool, str]:
@ -200,7 +203,7 @@ class ColourChannelDetectLUV(BackgroundDetectAlgorithm):
""" """
sample_coverage = self.get_sample_coverage(image) sample_coverage = self.get_sample_coverage(image)
is_sample = sample_coverage > self.min_sample_coverage is_sample = sample_coverage > self.settings.min_sample_coverage
message = f"{sample_coverage}% sample" message = f"{sample_coverage}% sample"
if not is_sample: if not is_sample:
message = "only " + message message = "only " + message

View file

@ -498,7 +498,7 @@ class BaseCamera(lt.Thing):
return self.active_detector.status return self.active_detector.status
@lt.thing_setting @lt.thing_setting
def background_detector_data(self) -> str: def background_detector_data(self) -> dict:
"""The data for each background detector, used to save to disk.""" """The data for each background detector, used to save to disk."""
data = {} data = {}
for name, obj in self.background_detectors.items(): for name, obj in self.background_detectors.items():
@ -511,9 +511,10 @@ class BaseCamera(lt.Thing):
"settings": obj.settings.model_dump(), "settings": obj.settings.model_dump(),
"background_data": bg_data, "background_data": bg_data,
} }
return data
@detector_name.setter @background_detector_data.setter
def detector_name(self, data: str) -> None: def background_detector_data(self, data: dict) -> None:
"""Set the data for each detector. This should only be called on init. """Set the data for each detector. This should only be called on init.
Do not call over HTTP. Would be good to have a way to make this private. Do not call over HTTP. Would be good to have a way to make this private.
@ -548,6 +549,8 @@ class BaseCamera(lt.Thing):
background = self.grab_jpeg(portal) background = self.grab_jpeg(portal)
background = np.array(Image.open(background.open())) background = np.array(Image.open(background.open()))
self.active_detector.set_background(background) self.active_detector.set_background(background)
# Manually save settings as the setter is not called.
self.save_settings()
CameraDependency = lt.deps.direct_thing_client_dependency(BaseCamera, "/camera/") CameraDependency = lt.deps.direct_thing_client_dependency(BaseCamera, "/camera/")

View file

@ -1,9 +1,6 @@
<template> <template>
<div class="uk-padding-small"> <div class="uk-padding-small">
<div v-show="!backendOK" class="uk-alert-danger"> <div>
The background detect Thing seems to be missing or incompatible.
</div>
<div v-show="backendOK">
<ul uk-accordion="multiple: true"> <ul uk-accordion="multiple: true">
<li> <li>
<a class="uk-accordion-title" href="#">Settings</a> <a class="uk-accordion-title" href="#">Settings</a>
@ -40,18 +37,10 @@
<script> <script>
import ActionButton from "../../labThingsComponents/actionButton.vue"; import ActionButton from "../../labThingsComponents/actionButton.vue";
import propertyControl from "../../labThingsComponents/propertyControl.vue";
export default { export default {
components: { components: {
ActionButton, ActionButton
propertyControl
},
computed: {
backendOK() {
return this.thingAvailable("background_detect");
}
}, },
methods: { methods: {