image.py
Go to the documentation of this file.
1 import sys
2 
3 from .registry import converts_from_numpy, converts_to_numpy
4 from sensor_msgs.msg import Image
5 
6 import numpy as np
7 from numpy.lib.stride_tricks import as_strided
8 
9 name_to_dtypes = {
10  "rgb8": (np.uint8, 3),
11  "rgba8": (np.uint8, 4),
12  "rgb16": (np.uint16, 3),
13  "rgba16": (np.uint16, 4),
14  "bgr8": (np.uint8, 3),
15  "bgra8": (np.uint8, 4),
16  "bgr16": (np.uint16, 3),
17  "bgra16": (np.uint16, 4),
18  "mono8": (np.uint8, 1),
19  "mono16": (np.uint16, 1),
20 
21  # for bayer image (based on cv_bridge.cpp)
22  "bayer_rggb8": (np.uint8, 1),
23  "bayer_bggr8": (np.uint8, 1),
24  "bayer_gbrg8": (np.uint8, 1),
25  "bayer_grbg8": (np.uint8, 1),
26  "bayer_rggb16": (np.uint16, 1),
27  "bayer_bggr16": (np.uint16, 1),
28  "bayer_gbrg16": (np.uint16, 1),
29  "bayer_grbg16": (np.uint16, 1),
30 
31  # OpenCV CvMat types
32  "8UC1": (np.uint8, 1),
33  "8UC2": (np.uint8, 2),
34  "8UC3": (np.uint8, 3),
35  "8UC4": (np.uint8, 4),
36  "8SC1": (np.int8, 1),
37  "8SC2": (np.int8, 2),
38  "8SC3": (np.int8, 3),
39  "8SC4": (np.int8, 4),
40  "16UC1": (np.uint16, 1),
41  "16UC2": (np.uint16, 2),
42  "16UC3": (np.uint16, 3),
43  "16UC4": (np.uint16, 4),
44  "16SC1": (np.int16, 1),
45  "16SC2": (np.int16, 2),
46  "16SC3": (np.int16, 3),
47  "16SC4": (np.int16, 4),
48  "32SC1": (np.int32, 1),
49  "32SC2": (np.int32, 2),
50  "32SC3": (np.int32, 3),
51  "32SC4": (np.int32, 4),
52  "32FC1": (np.float32, 1),
53  "32FC2": (np.float32, 2),
54  "32FC3": (np.float32, 3),
55  "32FC4": (np.float32, 4),
56  "64FC1": (np.float64, 1),
57  "64FC2": (np.float64, 2),
58  "64FC3": (np.float64, 3),
59  "64FC4": (np.float64, 4)
60 }
61 
62 @converts_to_numpy(Image)
63 def image_to_numpy(msg):
64  if not msg.encoding in name_to_dtypes:
65  raise TypeError('Unrecognized encoding {}'.format(msg.encoding))
66 
67  dtype_class, channels = name_to_dtypes[msg.encoding]
68  dtype = np.dtype(dtype_class)
69  dtype = dtype.newbyteorder('>' if msg.is_bigendian else '<')
70  shape = (msg.height, msg.width, channels)
71 
72  data = np.fromstring(msg.data, dtype=dtype).reshape(shape)
73  data.strides = (
74  msg.step,
75  dtype.itemsize * channels,
76  dtype.itemsize
77  )
78 
79  if channels == 1:
80  data = data[...,0]
81  return data
82 
83 
84 @converts_from_numpy(Image)
85 def numpy_to_image(arr, encoding):
86  if not encoding in name_to_dtypes:
87  raise TypeError('Unrecognized encoding {}'.format(encoding))
88 
89  im = Image(encoding=encoding)
90 
91  # extract width, height, and channels
92  dtype_class, exp_channels = name_to_dtypes[encoding]
93  dtype = np.dtype(dtype_class)
94  if len(arr.shape) == 2:
95  im.height, im.width, channels = arr.shape + (1,)
96  elif len(arr.shape) == 3:
97  im.height, im.width, channels = arr.shape
98  else:
99  raise TypeError("Array must be two or three dimensional")
100 
101  # check type and channels
102  if exp_channels != channels:
103  raise TypeError("Array has {} channels, {} requires {}".format(
104  channels, encoding, exp_channels
105  ))
106  if dtype_class != arr.dtype.type:
107  raise TypeError("Array is {}, {} requires {}".format(
108  arr.dtype.type, encoding, dtype_class
109  ))
110 
111  # make the array contiguous in memory, as mostly required by the format
112  contig = np.ascontiguousarray(arr)
113  im.data = contig.tostring()
114  im.step = contig.strides[0]
115  im.is_bigendian = (
116  arr.dtype.byteorder == '>' or
117  arr.dtype.byteorder == '=' and sys.byteorder == 'big'
118  )
119 
120  return im
def converts_from_numpy(msgtype, plural=False)
Definition: registry.py:17
def numpy_to_image(arr, encoding)
Definition: image.py:85
def converts_to_numpy(msgtype, plural=False)
Definition: registry.py:9
def image_to_numpy(msg)
Definition: image.py:63


ros_numpy
Author(s): Eric Wieser
autogenerated on Sat Oct 3 2020 03:25:57