Skip to content

Commit 1334824

Browse files
RSDK-1623 - decode custom depth mime type (#280)
Co-authored-by: Naveed Jooma <naveed@joo.ma>
1 parent f71c27c commit 1334824

File tree

4 files changed

+51
-2
lines changed

4 files changed

+51
-2
lines changed

data/fakeDM.vnd.viam.dep

424 Bytes
Binary file not shown.

src/viam/components/camera/camera.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ async def get_image(self, mime_type: str = "", *, timeout: Optional[float] = Non
3737
"""Get the next image from the camera as an Image or RawImage.
3838
Be sure to close the image when finished.
3939
40+
NOTE: If the mime type is ``image/vnd.viam.dep`` you can use :func:`viam.media.video.RawImage.bytes_to_depth_array`
41+
to convert the data to a standard representation.
42+
4043
Args:
4144
mime_type (str): The desired mime type of the image. This does not guarantee output type
4245

src/viam/media/video.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
from array import array
12
from enum import Enum
23
from io import BytesIO
3-
from typing import NamedTuple, Tuple, Union
4-
54
from PIL.Image import Image
5+
from typing import List, NamedTuple, Tuple, Union
66
from typing_extensions import Self
77

8+
from viam.errors import NotSupportedError
9+
810
from .viam_rgba_plugin import RGBA_FORMAT_LABEL
911

1012
LAZY_SUFFIX = "+lazy"
@@ -34,6 +36,27 @@ def close(self):
3436
"""Close the image and release resources. For RawImage, this is a noop."""
3537
return
3638

39+
def bytes_to_depth_array(self) -> List[List[int]]:
40+
"""Decode the data of an image that has the custom depth MIME type ``image/vnd.viam.dep`` into
41+
a standard representation.
42+
43+
Raises:
44+
NotSupportedError: Raised if given an image that is not of MIME type `image/vnd.viam.dep`.
45+
46+
Returns:
47+
List[List[int]]: The standard representation of the image.
48+
"""
49+
if self.mime_type != "image/vnd.viam.dep":
50+
raise NotSupportedError("Type must be `image/vnd.viam.dep` to use bytes_to_depth_array()")
51+
52+
width = int.from_bytes(self.data[8:16], "big")
53+
height = int.from_bytes(self.data[16:24], "big")
54+
depth_arr = array("H", self.data[24:])
55+
depth_arr.byteswap()
56+
57+
depth_arr_2d = [[depth_arr[row * width + col] for col in range(width)] for row in range(height)]
58+
return depth_arr_2d
59+
3760

3861
class CameraMimeType(str, Enum):
3962
VIAM_RGBA = "image/vnd.viam.rgba"

tests/test_media.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from array import array
2+
import os
3+
import pytest
4+
5+
from viam.media.video import RawImage
6+
7+
8+
class TestRawImage:
9+
@pytest.mark.asyncio
10+
async def test_bytes_to_depth_array(self):
11+
with open(f"{os.path.dirname(__file__)}/../data/fakeDM.vnd.viam.dep", "rb") as depth_map:
12+
image = RawImage(depth_map.read(), "image/vnd.viam.dep")
13+
assert isinstance(image, RawImage)
14+
standard_data = image.bytes_to_depth_array()
15+
assert len(standard_data) == 10
16+
assert len(standard_data[0]) == 20
17+
data_arr = array("H", image.data[24:])
18+
data_arr.byteswap()
19+
assert len(data_arr) == 200
20+
assert standard_data[0][0] == data_arr[0]
21+
assert standard_data[-1][3] == data_arr[183]
22+
assert standard_data[-1][3] == 9 * 3
23+
assert standard_data[4][4] == 4 * 4

0 commit comments

Comments
 (0)