Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converting ROS message with "8UC1" encoding to "mono8" fails. #175

Closed
NikolausDemmel opened this issue Jun 30, 2017 · 10 comments
Closed

Converting ROS message with "8UC1" encoding to "mono8" fails. #175

NikolausDemmel opened this issue Jun 30, 2017 · 10 comments

Comments

@NikolausDemmel
Copy link

I have ROS image messages with "8UC1" encoding (recorded from an Intel RealSense ZR300 with their driver http://wiki.ros.org/realsense_camera). I want to calibrate the camera using the Kalibr Toolbox, but I face an exception that traces back to the cv_bridge conversion.

Is the following expected to fail?

In [16]: CVB.imgmsg_to_cv2(I, desired_encoding="mono8")
---------------------------------------------------------------------------
CvBridgeError                             Traceback (most recent call last)
<ipython-input-16-8414acdc7ad8> in <module>()
----> 1 CVB.imgmsg_to_cv2(I, desired_encoding="mono8")

/opt/ros/kinetic/lib/python2.7/dist-packages/cv_bridge/core.pyc in imgmsg_to_cv2(self, img_msg, desired_encoding)
    182             res = cvtColor2(im, img_msg.encoding, desired_encoding)
    183         except RuntimeError as e:
--> 184             raise CvBridgeError(e)
    185 
    186         return res

CvBridgeError: [8UC1] is not a color format. but [mono8] is. The conversion does not make sense

In [17]: I.encoding
Out[17]: '8UC1'

I would have thought that "8UC1" is a valid encoding (according to http://docs.ros.org/api/sensor_msgs/html/msg/Image.html and http://docs.ros.org/kinetic/api/sensor_msgs/html/image__encodings_8h_source.html it is). Also, the Kalibr implementation seems to expect that this is working (see https://github.com/ethz-asl/kalibr/blob/a43a7b29bc43410b8a39a7f89d4c333d9cdad1f1/aslam_offline_calibration/kalibr/python/kalibr_common/ImageDatasetReader.py#L135-L137).

Is this something that maybe used to work?

I'm using the latest released version on ROS Kinetic / Ubuntu 16.04.

@wkentaro
Copy link
Member

wkentaro commented Jul 8, 2017

This is because 8UC and mono8 are not recognized as the same encoding.
ros/common_msgs#107 and #180 will fix this issue.

@NikolausDemmel
Copy link
Author

Thanks for the quick investigation and PRs!

@vrabaud
Copy link
Contributor

vrabaud commented Jul 10, 2017

I'll explain the error format: 8UC1 is not a color format, it just says that the image has one channel of size 8bit.
Mono8 is a color format: it is monochromatic with an 8bit channel.

Think about it this way: it does not make sense to convert 8UC3 to RGB as you don't know what you store in your 3 channels (could be BGR, YUV whatever). Same here, maybe your 1 channel is grayscale, maybe intensity, maybe it's not even color, it's a depth image.

@NikolausDemmel
Copy link
Author

@vrabaud, that makes sense, thanks. But does that mean you are suggesting to not support this conversion, or was it purely informational on top of @wkentaro's fix? I would think that interpreting 8UC1 as intensity when converting to mono8 is a reasonable assumption, no?

@vrabaud
Copy link
Contributor

vrabaud commented Jul 10, 2017

I would not take that risk: typing is what makes ROS strong so you should make sure your driver returns the proper type.
Just waiting for feedback on ros/common_msgs#107 to close this one.

@NikolausDemmel
Copy link
Author

@vrabaud, I see your point. I can ofc try to push for a change in the driver upstream.

However, sometimes you don't have control over your data source. I would also argue that it still can make sense to interpret something like a depth image encoded as 8UC1 as a greyscale image and do operations on that, so how would you implement that as opposed to https://github.com/ethz-asl/kalibr/blob/a43a7b29bc43410b8a39a7f89d4c333d9cdad1f1/aslam_offline_calibration/kalibr/python/kalibr_common/ImageDatasetReader.py#L135-L137? Does OpenCV distinguish between different single channel formats?

@NikolausDemmel
Copy link
Author

To answer my own question, it looks like converting from mono8 or 8UC without desired encoding results in the same cv image, right?

So in the linked example, one could write instead of

elif data.encoding == "8UC1" or data.encoding == "mono8":
      img_data = np.array(self.CVB.imgmsg_to_cv2(data, desired_encoding="mono8"))

simply

elif data.encoding == "8UC1" or data.encoding == "mono8":
      img_data = np.array(self.CVB.imgmsg_to_cv2(data))

right?

@tfoote
Copy link

tfoote commented Jul 10, 2017

Indeed the data representation is the same. The operation is more like downcasting. Where you can declare the datatype to be mono8 which is a subset of 8UC with specific semantic meaning. A conversion method should be relatively easy to implement, which simply changes the declared datatype on an assertion from the developer that says it's grayscale. Which would be useful if the datasource cannot be updated, or you want to play fast and loose with the data (but you're being explicit in your code, and the tools can enforce correctness).

@vrabaud
Copy link
Contributor

vrabaud commented Jul 11, 2017

@NikolausDemmel , right, in your case, that would work. But your driver should really return a "mono8"

@vrabaud vrabaud closed this as completed Jul 11, 2017
NikolausDemmel added a commit to NikolausDemmel/kalibr that referenced this issue Jul 11, 2017
Without this Kalibr errors when reading datasets where the image
encoding is "8UC1".

See ros-perception/vision_opencv#175 for an
explanation.
@martinakos
Copy link

what's the official solution to this?
I have the same problem using realsense2_camera node and camera_calibration.
Is there a way to remap the message type from 8UC1 to momo8 without having to change the code in realsense2_camera?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants