Skip to content

Commit 9878f0d

Browse files
authored
RSDK-11728 — Remove get_image, render_frame, and format (#1056)
1 parent 163ccd5 commit 9878f0d

File tree

18 files changed

+36
-264
lines changed

18 files changed

+36
-264
lines changed

docs/examples/example.ipynb

Lines changed: 9 additions & 19 deletions
Large diffs are not rendered by default.

examples/apis.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"importName": "GenericComponent"
2424
},
2525
"camera": {
26-
"func": "get_image",
26+
"func": "get_images",
2727
"packagePath": "viam.components"
2828
},
2929
"encoder": {

examples/server/v1/client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from viam.components.camera import Camera
88
from viam.components.encoder import Encoder
99
from viam.components.motor import Motor
10+
from viam.media.utils.pil import viam_to_pil_image
1011
from viam.media.video import CameraMimeType
1112
from viam.robot.client import RobotClient
1213
from viam.rpc.dial import DialOptions
@@ -34,7 +35,8 @@ async def client():
3435

3536
print("\n#### CAMERA ####")
3637
camera = Camera.from_robot(robot, "camera0")
37-
img = await camera.get_image(mime_type=CameraMimeType.PNG)
38+
images, _ = await camera.get_images()
39+
img = viam_to_pil_image(images[0])
3840
assert isinstance(img, Image)
3941
img.show()
4042
await asyncio.sleep(1)

examples/server/v1/components.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
else:
1010
from typing import AsyncIterator
1111

12-
from datetime import timedelta
12+
from datetime import datetime, timedelta
1313
from io import BytesIO
1414
from multiprocessing import Lock
1515
from pathlib import Path
1616
from typing import Any, Dict, List, Mapping, Optional, Tuple
1717

18+
from google.protobuf.timestamp_pb2 import Timestamp
1819
from PIL import Image
1920

2021
from viam.components.arm import Arm
@@ -434,11 +435,11 @@ def __init__(self, name: str):
434435
img.close()
435436
super().__init__(name)
436437

437-
async def get_image(self, mime_type: str = "", extra: Optional[Dict[str, Any]] = None, **kwargs) -> ViamImage:
438-
return self.image
439-
440438
async def get_images(self, timeout: Optional[float] = None, **kwargs) -> Tuple[List[NamedImage], ResponseMetadata]:
441-
raise NotImplementedError()
439+
ts = Timestamp()
440+
ts.FromDatetime(datetime.now())
441+
metadata = ResponseMetadata(captured_at=ts)
442+
return [NamedImage(self.name, self.image.data, self.image.mime_type)], metadata
442443

443444
async def get_point_cloud(self, extra: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[bytes, str]:
444445
raise NotImplementedError()

src/viam/app/data_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ async def get_latest_tabular_data(
571571
part_id="77ae3145-7b91-123a-a234-e567cdca8910",
572572
resource_name="camera-1",
573573
resource_api="rdk:component:camera",
574-
method_name="GetImage",
574+
method_name="GetImages",
575575
additional_params={"docommand_input": {"test": "test"}}
576576
)
577577

src/viam/components/camera/camera.py

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import sys
33
from typing import Any, Dict, Final, Optional, Sequence, Tuple
44

5-
from viam.media.video import NamedImage, ViamImage
5+
from viam.media.video import NamedImage
66
from viam.proto.common import ResponseMetadata
77
from viam.proto.component.camera import GetPropertiesResponse
88
from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT
@@ -36,32 +36,6 @@ class Camera(ComponentBase):
3636

3737
Properties: "TypeAlias" = GetPropertiesResponse
3838

39-
@abc.abstractmethod
40-
async def get_image(
41-
self, mime_type: str = "", *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
42-
) -> ViamImage:
43-
"""Get the next image from the camera as a ViamImage.
44-
Be sure to close the image when finished.
45-
46-
NOTE: If the mime type is ``image/vnd.viam.dep`` you can use :func:`viam.media.video.ViamImage.bytes_to_depth_array`
47-
to convert the data to a standard representation.
48-
49-
::
50-
51-
my_camera = Camera.from_robot(machine, "my_camera")
52-
frame = await my_camera.get_image()
53-
print(f"Frame: {frame}")
54-
55-
Args:
56-
mime_type (str): The desired mime type of the image. This does not guarantee output type
57-
58-
Returns:
59-
ViamImage: The frame.
60-
61-
For more information, see `Camera component <https://docs.viam.com/dev/reference/apis/components/camera/#getimage>`_.
62-
"""
63-
...
64-
6539
@abc.abstractmethod
6640
async def get_images(
6741
self,

src/viam/components/camera/client.py

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
from grpclib.client import Channel
44

5-
from viam.media.video import CameraMimeType, NamedImage, ViamImage
5+
from viam.media.video import CameraMimeType, NamedImage
66
from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, ResponseMetadata
77
from viam.proto.component.camera import (
88
CameraServiceStub,
9-
GetImageRequest,
10-
GetImageResponse,
119
GetImagesRequest,
1210
GetImagesResponse,
1311
GetPointCloudRequest,
@@ -30,19 +28,6 @@ def __init__(self, name: str, channel: Channel):
3028
self.client = CameraServiceStub(channel)
3129
super().__init__(name)
3230

33-
async def get_image(
34-
self,
35-
mime_type: str = "",
36-
*,
37-
extra: Optional[Dict[str, Any]] = None,
38-
timeout: Optional[float] = None,
39-
**kwargs,
40-
) -> ViamImage:
41-
md = kwargs.get("metadata", self.Metadata()).proto
42-
request = GetImageRequest(name=self.name, mime_type=mime_type, extra=dict_to_struct(extra))
43-
response: GetImageResponse = await self.client.GetImage(request, timeout=timeout, metadata=md)
44-
return ViamImage(response.image, CameraMimeType.from_string(response.mime_type))
45-
4631
async def get_images(
4732
self,
4833
*,
@@ -56,11 +41,7 @@ async def get_images(
5641
response: GetImagesResponse = await self.client.GetImages(request, timeout=timeout, metadata=md)
5742
imgs = []
5843
for img_data in response.images:
59-
if img_data.mime_type:
60-
mime_type = CameraMimeType.from_string(img_data.mime_type)
61-
else:
62-
# TODO(RSDK-11728): remove this once we deleted the format field
63-
mime_type = CameraMimeType.from_proto(img_data.format)
44+
mime_type = CameraMimeType.from_string(img_data.mime_type)
6445
img = NamedImage(img_data.source_name, img_data.image, mime_type)
6546
imgs.append(img)
6647
resp_metadata: ResponseMetadata = response.response_metadata

src/viam/components/camera/service.py

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
11
# TODO: Update type checking based with RSDK-4089
22
# pyright: reportGeneralTypeIssues=false
3-
from google.api.httpbody_pb2 import HttpBody # type: ignore
43
from grpclib.server import Stream
54

6-
from viam.media.video import CameraMimeType
5+
from viam.errors import NotSupportedError
76
from viam.proto.common import DoCommandRequest, DoCommandResponse, GetGeometriesRequest, GetGeometriesResponse
87
from viam.proto.component.camera import (
98
CameraServiceBase,
10-
GetImageRequest,
11-
GetImageResponse,
129
GetImagesRequest,
1310
GetImagesResponse,
1411
GetPointCloudRequest,
1512
GetPointCloudResponse,
1613
GetPropertiesRequest,
1714
GetPropertiesResponse,
1815
Image,
19-
RenderFrameRequest,
2016
)
2117
from viam.resource.rpc_service_base import ResourceRPCServiceBase
2218
from viam.utils import dict_to_struct, struct_to_dict
@@ -31,16 +27,13 @@ class CameraRPCService(CameraServiceBase, ResourceRPCServiceBase[Camera]):
3127

3228
RESOURCE_TYPE = Camera
3329

34-
async def GetImage(self, stream: Stream[GetImageRequest, GetImageResponse]) -> None:
35-
request = await stream.recv_message()
36-
assert request is not None
37-
name = request.name
38-
camera = self.get_resource(name)
30+
async def GetImage(self, stream: Stream) -> None:
31+
"""Deprecated: Use GetImages instead."""
32+
raise NotSupportedError("GetImage is deprecated. Use GetImages instead.")
3933

40-
timeout = stream.deadline.time_remaining() if stream.deadline else None
41-
image = await camera.get_image(request.mime_type, extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
42-
response = GetImageResponse(mime_type=image.mime_type, image=image.data)
43-
await stream.send_message(response)
34+
async def RenderFrame(self, stream: Stream) -> None:
35+
"""Deprecated: Use GetImages instead."""
36+
raise NotSupportedError("RenderFrame is deprecated. Use GetImages instead.")
4437

4538
async def GetImages(self, stream: Stream[GetImagesRequest, GetImagesResponse]) -> None:
4639
request = await stream.recv_message()
@@ -56,25 +49,11 @@ async def GetImages(self, stream: Stream[GetImagesRequest, GetImagesResponse]) -
5649
)
5750
img_bytes_lst = []
5851
for img in images:
59-
mime_type = CameraMimeType.from_string(img.mime_type)
60-
# TODO(RSDK-11728): remove this fmt logic once we deleted the format field
61-
fmt = mime_type.to_proto() # Will be Format.FORMAT_UNSPECIFIED if an unsupported/custom mime type is set
62-
6352
img_bytes = img.data
64-
img_bytes_lst.append(Image(source_name=img.name, mime_type=img.mime_type, format=fmt, image=img_bytes))
53+
img_bytes_lst.append(Image(source_name=img.name, mime_type=img.mime_type, image=img_bytes))
6554
response = GetImagesResponse(images=img_bytes_lst, response_metadata=metadata)
6655
await stream.send_message(response)
6756

68-
async def RenderFrame(self, stream: Stream[RenderFrameRequest, HttpBody]) -> None: # pyright: ignore [reportInvalidTypeForm]
69-
request = await stream.recv_message()
70-
assert request is not None
71-
name = request.name
72-
camera = self.get_resource(name)
73-
timeout = stream.deadline.time_remaining() if stream.deadline else None
74-
image = await camera.get_image(request.mime_type, timeout=timeout, metadata=stream.metadata)
75-
response = HttpBody(data=image.data, content_type=image.mime_type) # type: ignore
76-
await stream.send_message(response)
77-
7857
async def GetPointCloud(self, stream: Stream[GetPointCloudRequest, GetPointCloudResponse]) -> None:
7958
request = await stream.recv_message()
8059
assert request is not None

src/viam/media/video.py

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from typing_extensions import ClassVar, Self
55

66
from viam.errors import NotSupportedError
7-
from viam.proto.component.camera import Format
87

98
from .viam_rgba import RGBA_HEADER_LENGTH, RGBA_MAGIC_NUMBER
109

@@ -70,44 +69,6 @@ def from_string(cls, value: str) -> Self:
7069
value_mime = value[:-5] if value.endswith("+lazy") else value # ViamImage lazy encodes by default
7170
return cls(value_mime)
7271

73-
@classmethod
74-
def from_proto(cls, format: Format.ValueType) -> Self:
75-
"""Returns the mimetype from a proto enum.
76-
77-
Args:
78-
format (Format.ValueType): The mimetype in a proto enum.
79-
80-
Returns:
81-
Self: The mimetype.
82-
"""
83-
mimetypes = {
84-
Format.FORMAT_RAW_RGBA: cls.VIAM_RGBA,
85-
Format.FORMAT_RAW_DEPTH: cls.VIAM_RAW_DEPTH,
86-
Format.FORMAT_JPEG: cls.JPEG,
87-
Format.FORMAT_PNG: cls.PNG,
88-
}
89-
return cls(mimetypes.get(format, cls.JPEG))
90-
91-
@property
92-
def proto(self) -> Format.ValueType:
93-
"""Returns the mimetype in a proto enum.
94-
95-
Returns:
96-
Format.ValueType: The mimetype in a proto enum.
97-
"""
98-
formats = {
99-
self.VIAM_RGBA: Format.FORMAT_RAW_RGBA,
100-
self.VIAM_RAW_DEPTH: Format.FORMAT_RAW_DEPTH,
101-
self.JPEG: Format.FORMAT_JPEG,
102-
self.PNG: Format.FORMAT_PNG,
103-
}
104-
return formats.get(self, Format.FORMAT_UNSPECIFIED)
105-
106-
def to_proto(self) -> Format.ValueType:
107-
"""
108-
DEPRECATED: Use `CameraMimeType.proto`
109-
"""
110-
return self.proto
11172

11273

11374
CameraMimeType.VIAM_RGBA = CameraMimeType.from_string("image/vnd.viam.rgba")

src/viam/proto/component/camera/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from ....gen.component.camera.v1.camera_grpc import CameraServiceBase, CameraServiceStub, UnimplementedCameraServiceBase
77
from ....gen.component.camera.v1.camera_pb2 import (
88
DistortionParameters,
9-
Format,
109
GetImageRequest,
1110
GetImageResponse,
1211
GetImagesRequest,
@@ -28,7 +27,6 @@
2827
"CameraServiceStub",
2928
"UnimplementedCameraServiceBase",
3029
"DistortionParameters",
31-
"Format",
3230
"GetImageRequest",
3331
"GetImageResponse",
3432
"GetImagesRequest",

0 commit comments

Comments
 (0)