diff --git a/__pycache__/test_local.cpython-314-pytest-9.0.1.pyc b/__pycache__/test_local.cpython-314-pytest-9.0.1.pyc new file mode 100644 index 0000000..eb16827 Binary files /dev/null and b/__pycache__/test_local.cpython-314-pytest-9.0.1.pyc differ diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 diff --git a/meta.json b/meta.json index 009ee64..02f0f72 100644 --- a/meta.json +++ b/meta.json @@ -17,8 +17,7 @@ "path": "dist/main", "arch": [ "linux/amd64", - "linux/arm64", - "darwin/amd64" + "linux/arm64" ] }, "entrypoint": "dist/main" diff --git a/src/torchvision_module.py b/src/torchvision_module.py index 9a2f5b7..cec69d7 100644 --- a/src/torchvision_module.py +++ b/src/torchvision_module.py @@ -1,9 +1,9 @@ """Module that defines the Vision Service that wraps torchvision functionality""" -from typing import ClassVar, List, Mapping, Sequence, Any, Dict, Optional, Union +from typing import ClassVar, List, Mapping, Sequence, Any, Dict, Optional, Union, Tuple from typing_extensions import Self from viam.components.camera import Camera -from viam.media.video import ViamImage, CameraMimeType +from viam.media.video import ViamImage from viam.proto.service.vision import Classification, Detection from viam.services.vision import Vision, CaptureAllResult from viam.module.types import Reconfigurable @@ -47,7 +47,7 @@ def new_service( return service @classmethod - def validate_config(cls, config: ServiceConfig) -> Sequence[str]: + def validate_config(cls, config: ServiceConfig) -> Tuple[Sequence[str], Sequence[str]]: """Validates JSON Configuration""" model_name = config.attributes.fields["model_name"].string_value camera_name = config.attributes.fields["camera_name"].string_value @@ -60,7 +60,7 @@ def validate_config(cls, config: ServiceConfig) -> Sequence[str]: raise Exception( "A camera name is required for this vision service module." ) - return [camera_name] + return [camera_name], [] def reconfigure( self, config: ServiceConfig, dependencies: Mapping[ResourceName, ResourceBase] @@ -197,19 +197,21 @@ async def capture_all_from_camera( "is not the configured 'camera_name'", self.camera_name, ) - image = await self.camera.get_image(mime_type=CameraMimeType.JPEG) + images, _ = await self.camera.get_images() + if images is None or len(images) == 0 and (return_image or return_classifications or return_detections): + raise ValueError("No images returned by get_images") if return_image: - result.image = image + result.image = images[0] if return_classifications: try: - classifications = await self.get_classifications(image, 1) + classifications = await self.get_classifications(images[0], 1) result.classifications = classifications # pylint: disable=broad-exception-caught except Exception as e: LOGGER.info(f"getClassifications failed: {e}") if return_detections: try: - detections = await self.get_detections(image, timeout=timeout, extra=None) + detections = await self.get_detections(images[0], timeout=timeout, extra=None) result.detections = detections # pylint: disable=broad-exception-caught except Exception as e: @@ -362,8 +364,10 @@ def filter_output( async def get_image_from_dependency(self, camera_name: str): # cam = self.dependencies[Camera.get_resource_name("")] - im = await self.camera.get_image(mime_type=CameraMimeType.JPEG) - return decode_image(im) + imgs, _ = await self.camera.get_images() + if imgs is None or len(imgs) == 0: + raise ValueError("No images returned by get_images") + return decode_image(imgs[0]) def wrap_detections(self, prediction: dict, image_shape: Sequence[int]): """_summary_ diff --git a/tests/__pycache__/test_torchvision.cpython-314-pytest-9.0.1.pyc b/tests/__pycache__/test_torchvision.cpython-314-pytest-9.0.1.pyc new file mode 100644 index 0000000..8e95284 Binary files /dev/null and b/tests/__pycache__/test_torchvision.cpython-314-pytest-9.0.1.pyc differ diff --git a/tests/test_torchvision.py b/tests/test_torchvision.py index 2218ee0..465867b 100644 --- a/tests/test_torchvision.py +++ b/tests/test_torchvision.py @@ -65,8 +65,8 @@ class TestVision: @pytest.mark.asyncio async def test_validate(self): with pytest.raises(Exception): - response = TorchVisionService.validate_config(config=config) - response = TorchVisionService.validate_config(config=config2) + response, _ = TorchVisionService.validate_config(config=config) + response, _ = TorchVisionService.validate_config(config=config2) @pytest.mark.asyncio @patch('viam.components.camera.Camera.get_resource_name', return_value="fake_cam") @@ -90,7 +90,7 @@ def test_capture_all_from_camera(self, fake_cam): camera.camera_name = "fake_cam" camera.reconfigure(cfg, dependencies={"fake_cam": Mock()}) - camera.camera.get_image = AsyncMock(return_value=pil_to_viam_image(image, mime_type=CameraMimeType.JPEG)) + camera.camera.get_images = AsyncMock(return_value=[[pil_to_viam_image(image, mime_type=CameraMimeType.JPEG)], None]) # without point clouds = True result = asyncio.run(camera.capture_all_from_camera( @@ -126,7 +126,7 @@ def test_default_camera_behavior(self, fake_cam): ) vs.reconfigure(cfg, dependencies={"fake_cam": Mock()}) - vs.camera.get_image = AsyncMock(return_value=pil_to_viam_image(image, mime_type=CameraMimeType.JPEG)) + vs.camera.get_images = AsyncMock(return_value=[[pil_to_viam_image(image, mime_type=CameraMimeType.JPEG)], None]) result = vs.get_classifications_from_camera( "",