Re: [ros-users] Python cv_bridge

Top Page
Attachments:
Message as email
+ (text/plain)
+ cv_bridge.patch (text/x-diff)
Delete this message
Reply to this message
Author: Advait Jain
Date:  
To: ros-users
Subject: Re: [ros-users] Python cv_bridge
Attached is a patch that seems to work for desired_encoding = 'passthrough'.

Also, from the opencv python cookbok there should be a cv.fromarray to go
from cvMat to numpy array. I don't see this in the vision_opencv-1.0.3.
What version of the vision_opencv stack does the online documentation
correspond to?


On Thu, Jun 10, 2010 at 9:00 PM, Advait Jain <> wrote:
> In the python implementation of cv_bridge the imgmsg_to_cv function
> returns a CvMat object instead of an IplImage. This is different from the
> documentation and the C++ implementation. Is this intentional or a bug?
>
> Advait
>

Index: cv_bridge.py
===================================================================
--- cv_bridge.py    (revision 30223)
+++ cv_bridge.py    (working copy)
@@ -67,6 +67,21 @@
           fmt = "BGRA"
         return fmt


+
+    def encoding_to_depth_channels(self, encoding):
+        d = {
+            'rgb8': (cv.IPL_DEPTH_8U, 3),
+            'bgr8': (cv.IPL_DEPTH_8U, 3),
+            'rgba8': (cv.IPL_DEPTH_8U, 4),
+            'bgra8': (cv.IPL_DEPTH_8U, 4),
+            'mono8': (cv.IPL_DEPTH_8U, 1),
+            'mono16': (cv.IPL_DEPTH_16U, 1)
+            }
+        if encoding in d:
+            return d[encoding]
+        else:
+            raise RuntimeError('unknown encoding: '+encoding)
+
     def imgmsg_to_cv(self, img_msg, desired_encoding = "passthrough"):
         """
         Convert a sensor_msgs::Image message to an OpenCV :ctype:`IplImage`.
@@ -102,46 +117,46 @@
         This function returns an OpenCV :ctype:`IplImage` message on success, or raises :exc:`opencv_latest.cv_bridge.CvBridgeError` on failure.
         """


-        source_type = self.encoding_as_cvtype(img_msg.encoding)
-        im = cv.CreateMatHeader(img_msg.height, img_msg.width, source_type)
+        depth, channels = self.encoding_to_depth_channels(img_msg.encoding)
+        im = cv.CreateImageHeader((img_msg.width, img_msg.height), depth, channels)
         cv.SetData(im, img_msg.data, img_msg.step)


         if desired_encoding == "passthrough":
             return im


-        # Might need to do a conversion.  sourcefmt and destfmt can be
-        # one of GRAY, RGB, BGR, RGBA, BGRA.
-        sourcefmt = self.encoding_as_fmt(img_msg.encoding)
-        destfmt = self.encoding_as_fmt(desired_encoding)
+#        # Might need to do a conversion.  sourcefmt and destfmt can be
+#        # one of GRAY, RGB, BGR, RGBA, BGRA.
+#        sourcefmt = self.encoding_as_fmt(img_msg.encoding)
+#        destfmt = self.encoding_as_fmt(desired_encoding)
+#
+#        source_type = self.encoding_as_cvtype(img_msg.encoding)
+#        destination_type = self.encoding_as_cvtype(desired_encoding)
+#        if sourcefmt == destfmt and source_type == destination_type:
+#            return im
+#
+#        # First want to make sure that source depth matches destination depth
+#        if source_type != destination_type:
+#            # im2 is the intermediate image. It has the same # channels as source_type,
+#            # but the depth of destination_type.
+#
+#            # XXX - these macros were missing from OpenCV Python, so roll our own here:
+#            CV_CN_SHIFT = 3
+#            def CV_MAKETYPE(depth,cn):
+#                return cv.CV_MAT_DEPTH(depth) + ((cn - 1) << CV_CN_SHIFT)
+#
+#            im2_type = CV_MAKETYPE(destination_type, cv.CV_MAT_CN(source_type))
+#            im2 = cv.CreateMat(img_msg.height, img_msg.width, im2_type)
+#            cv.ConvertScale(im, im2)
+#        else:
+#            im2 = im
+#
+#        if sourcefmt != destfmt:
+#            im3 = cv.CreateMat(img_msg.height, img_msg.width, destination_type)
+#            cv.CvtColor(im2, im3, eval("cv.CV_%s2%s" % (sourcefmt, destfmt)))
+#        else:
+#            im3 = im2
+#        return im3


-        source_type = self.encoding_as_cvtype(img_msg.encoding)
-        destination_type = self.encoding_as_cvtype(desired_encoding)
-        if sourcefmt == destfmt and source_type == destination_type:
-            return im
-
-        # First want to make sure that source depth matches destination depth
-        if source_type != destination_type:
-            # im2 is the intermediate image. It has the same # channels as source_type,
-            # but the depth of destination_type.
-
-            # XXX - these macros were missing from OpenCV Python, so roll our own here:
-            CV_CN_SHIFT = 3
-            def CV_MAKETYPE(depth,cn):
-                return cv.CV_MAT_DEPTH(depth) + ((cn - 1) << CV_CN_SHIFT)
-
-            im2_type = CV_MAKETYPE(destination_type, cv.CV_MAT_CN(source_type))
-            im2 = cv.CreateMat(img_msg.height, img_msg.width, im2_type)
-            cv.ConvertScale(im, im2)
-        else:
-            im2 = im
-
-        if sourcefmt != destfmt:
-            im3 = cv.CreateMat(img_msg.height, img_msg.width, destination_type)
-            cv.CvtColor(im2, im3, eval("cv.CV_%s2%s" % (sourcefmt, destfmt)))
-        else:
-            im3 = im2
-        return im3
-
     def cv_to_imgmsg(self, cvim, encoding = "passthrough"):
         """


@@ -188,3 +203,6 @@
         img_msg.step = img_msg.width * cv.CV_MAT_CN(cv.GetElemType(cvim))
         img_msg.data = cvim.tostring()
         return img_msg
+
+
+