From 95e19cf6012f3f260c841f438794f3534d6e484c Mon Sep 17 00:00:00 2001 From: Casey Stone Date: Thu, 1 May 2025 17:10:19 -0500 Subject: [PATCH 1/2] added barcode reading action --- pyproject.toml | 3 ++- src/camera_rest_node.py | 49 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9dc9257..71cf973 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..f680915 100644 --- a/src/camera_rest_node.py +++ b/src/camera_rest_node.py @@ -12,6 +12,7 @@ from madsci.node_module.rest_node_module import RestNode from camera_config import CameraConfig +from pyzbar.pyzbar import decode class CameraNode(RestNode): @@ -48,6 +49,45 @@ def take_picture( camera.release() 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 = s = all_detected_barcodes[0].data.decode("utf-8") + + except Error as e: + raise e + + return ActionSucceeded(data={"barcode": barcode}) + def adjust_focus_settings( self, @@ -93,6 +133,15 @@ def adjust_focus_settings( camera.read() + + + + + + + + + if __name__ == "__main__": camera_node = CameraNode() camera_node.start_node() From 794af09f21c6a898063fc1fb3d10c55380f088df Mon Sep 17 00:00:00 2001 From: Casey Stone Date: Mon, 5 May 2025 12:39:58 -0500 Subject: [PATCH 2/2] fixed pre-commit checks --- pyproject.toml | 2 +- src/camera_rest_node.py | 38 ++++++++++++++------------------------ 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 71cf973..3b975a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ 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" diff --git a/src/camera_rest_node.py b/src/camera_rest_node.py index f680915..aeaa0fd 100644 --- a/src/camera_rest_node.py +++ b/src/camera_rest_node.py @@ -10,9 +10,9 @@ 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 -from pyzbar.pyzbar import decode class CameraNode(RestNode): @@ -49,45 +49,44 @@ def take_picture( camera.release() return ActionSucceeded(files={"image": temp_file_path}) - + @action def read_barcode( - self, + 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. + 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: + 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. + 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: + try: # take an image and collect the image path - action_result = self.take_picture(focus=focus, autofocus=autofocus) - image_path = action_result.files['image'] + 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: + if all_detected_barcodes: # Note: only collects the first in a potential list of barcodes - barcode = s = all_detected_barcodes[0].data.decode("utf-8") + barcode = all_detected_barcodes[0].data.decode("utf-8") - except Error as e: + except Exception as e: raise e - - return ActionSucceeded(data={"barcode": barcode}) + return ActionSucceeded(data={"barcode": barcode}) def adjust_focus_settings( self, @@ -133,15 +132,6 @@ def adjust_focus_settings( camera.read() - - - - - - - - - if __name__ == "__main__": camera_node = CameraNode() camera_node.start_node()