I'm new to ROS and running ROS noetic with the need to create a ROS bag containing uncompressed greyscale images.
Therefore, I use rosbags-image==0.9.1 and according to their
compressed example here
I have prepared an example to save 2 uncompressed mono8
images, stored on disk as png.
Image size is 225x224 which results in data size of 50400 bytes.
# Test to store 225x224 mono8 images uncompressed in ros bag for noetic
import numpy
from rosbags.rosbag1 import Writer
from rosbags.serde import serialize_ros1, serialize_cdr
from rosbags.typesys.types import builtin_interfaces__msg__Time as Time
# from rosbags.typesys.types import sensor_msgs__msg__CompressedImage as CompressedImage
from rosbags.typesys.types import sensor_msgs__msg__Image as Image
from rosbags.typesys.types import std_msgs__msg__Header as Header
from cv2 import imread
TOPIC = '/camera'
FRAMEID = 'map'
# Contains filenames and their timestamps
IMAGES = [
('homer.png', 42), # w x h = 225 x 224, 8bit
('marge.png', 43), # w x h = 225 x 224, 8bit
]
def save_images() -> None:
"""Iterate over IMAGES and save to output bag."""
with Writer('output.bag') as writer:
conn = writer.add_connection(TOPIC, Image.__msgtype__)
for path, timestamp in IMAGES:
ii = imread(path, 0) # test version 1: <type 'numpy.ndarray'>
dd = numpy.fromfile(path, dtype=numpy.uint8) # version 2: <type 'numpy.ndarray'>
print(ii.size, dd.size)
# ii.size=50400 = correct uncompressed img data size
# vs dd.size=44157 = correct png filesize
message = Image(
Header(
stamp=Time(
sec=int(timestamp // 10**9),
nanosec=int(timestamp % 10**9),
),
frame_id=FRAMEID,
),
height=ii.shape[0], # 224
width=ii.shape[1], # 225
encoding='mono8', # 8bit
is_bigendian=0, # False
step=ii.shape[1], # 225
# data=ii, # ii.size = 50400=hxw, ERROR!!!
# ValueError: memoryview assignment: lvalue and rvalue have different structures
data=dd, # dd.size = 44157=png-file size, # Runs, but bag fails to deserialize image in rviz
)
writer.write(
conn,
timestamp,
serialize_ros1(message, Image.__msgtype__),
)
save_images()
Can someone please explain, what's wrong with the code, why setting the (imho) correct ii data results in an error ValueError: memoryview assignment: lvalue and rvalue have different structures
, while setting the smaller dd data can be written,
but seems to be wrong as well...