diff --git a/pyproject.toml b/pyproject.toml index 9dc9257..3b975a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,8 @@ dependencies = [ "madsci.node_module>=0.1.9", "madsci.client>=0.1.9", "madsci.common>=0.1.9", - "numpy<2" + "numpy<2", + "pyzbar", ] requires-python = ">=3.9.1" readme = "README.md" diff --git a/src/camera_rest_node.py b/src/camera_rest_node.py index c973c37..aeaa0fd 100644 --- a/src/camera_rest_node.py +++ b/src/camera_rest_node.py @@ -10,6 +10,7 @@ from madsci.common.types.action_types import ActionResult, ActionSucceeded from madsci.node_module.helpers import action from madsci.node_module.rest_node_module import RestNode +from pyzbar.pyzbar import decode from camera_config import CameraConfig @@ -49,6 +50,44 @@ def take_picture( return ActionSucceeded(files={"image": temp_file_path}) + @action + def read_barcode( + self, + focus: Optional[int] = None, + autofocus: Optional[bool] = None, + ) -> ActionResult: + """ + Takes an image and returns the values of any barcodes present in the image. Camera focus can be adjusted using the provided parameters if necessary. + + Args: + camera (cv2.VideoCapture): The camera object to adjust focus for. + focus (Optional[int]): The desired focus value (used if autofocus is disabled). + autofocus (Optional[bool]): Whether to enable or disable autofocus. + + Returns: + ActionSucceded regardless of if barcode is collected or not. + Barcode field in ActionResult data dictionary will contain 'None' if no barcode was collected + + """ + try: + # take an image and collect the image path + action_result = self.take_picture(focus=focus, autofocus=autofocus) + image_path = action_result.files["image"] + + # try to collect the barcode from the image + image = cv2.imread(image_path) + barcode = None + + all_detected_barcodes = decode(image) + if all_detected_barcodes: + # Note: only collects the first in a potential list of barcodes + barcode = all_detected_barcodes[0].data.decode("utf-8") + + except Exception as e: + raise e + + return ActionSucceeded(data={"barcode": barcode}) + def adjust_focus_settings( self, camera: cv2.VideoCapture,