예제 #1
0
    def process(raw_msg, model, out, flags):
        '''
        Given an original image message (sensor_msgs/Image), fill in the out ImageSet with the
        processed (debayered, rectified, grayscaled) images (in numpy format) based on the flags.
        @param raw_msg: sensor_msgs/Image original image message to process
        @param model: image_geometry.PinholeCameraModel object used to rectify images if RECT or RECT_COLOR flag is set.
                      Can just pass in None if you aren't using RECT or RECT_COLOR
        @param out: an ImageSet object. The requested images will be set in out based on the flags bitmask
        @param flags: an integer bitmask inticating which processed images you want in out.
                      ex: process(msg, model, out, ImageProc.RECT_COLOR | ImageProc.RECT)
                      will fill the raw, rect_color, and rect images in out.
        '''
        # always set raw
        out.raw = ImageProc.bridge.imgmsg_to_cv2(raw_msg)
        if not bool(flags & ImageProc.ALL):
            return
        mono = ImageProc.MONO | ImageProc.RECT
        color = ImageProc.COLOR | ImageProc.RECT_COLOR

        # Check that camera model is set if we are rectifying an image
        rect = bool(ImageProc.RECT | ImageProc.RECT_COLOR)
        if rect and not isinstance(model, PinholeCameraModel):
            raise Exception(
                'camera model is not a PinholeCameraModel instance')

        raw_encoding = raw_msg.encoding
        # convert bayer to color and mono as needed
        if raw_encoding.find('bayer') != -1:
            if color:
                out.color = cvtColor2(out.raw, raw_encoding, 'bgr8')
                out.color_encoding = 'bgr8'
            if mono:
                out.mono = cvtColor2(out.raw, raw_encoding, 'mono8')
        elif raw_encoding.find('mono') != -1:
            if mono:
                out.mono = out.raw
            if color:
                raise Exception('cant get color from mono image')
        else:  # Otherwise assume color
            if mono:
                out.mono = cvtColor2(out.raw, raw_encoding, 'mono8')
            if color:
                out.color = out.raw
                out.color_encoding = raw_encoding
        if flags & ImageProc.RECT:
            if out.rect is None:
                out.rect = np.zeros(out.mono.shape)
            model.rectifyImage(out.mono, out.rect)
        if flags & ImageProc.RECT_COLOR:
            if out.rect_color is None:
                out.rect_color = np.zeros(out.color.shape, out.color.dtype)
            model.rectifyImage(out.color, out.rect_color)
예제 #2
0
    def process(raw_msg, model, out, flags):
        '''
        Given an original image message (sensor_msgs/Image), fill in the out ImageSet with the
        processed (debayered, rectified, grayscaled) images (in numpy format) based on the flags.
        @param raw_msg: sensor_msgs/Image original image message to process
        @param model: image_geometry.PinholeCameraModel object used to rectify images if RECT or RECT_COLOR flag is set.
                      Can just pass in None if you aren't using RECT or RECT_COLOR
        @param out: an ImageSet object. The requested images will be set in out based on the flags bitmask
        @param flags: an integer bitmask inticating which processed images you want in out.
                      ex: process(msg, model, out, ImageProc.RECT_COLOR | ImageProc.RECT)
                      will fill the raw, rect_color, and rect images in out.
        '''
        # always set raw
        out.raw = ImageProc.bridge.imgmsg_to_cv2(raw_msg)
        if not bool(flags & ImageProc.ALL):
            return
        mono = ImageProc.MONO | ImageProc.RECT
        color = ImageProc.COLOR | ImageProc.RECT_COLOR

        # Check that camera model is set if we are rectifying an image
        rect = bool(ImageProc.RECT | ImageProc.RECT_COLOR)
        if rect and not isinstance(model, PinholeCameraModel):
            raise Exception('camera model is not a PinholeCameraModel instance')

        raw_encoding = raw_msg.encoding
        # convert bayer to color and mono as needed
        if raw_encoding.find('bayer') != -1:
            if color:
                out.color = cvtColor2(out.raw, raw_encoding, 'bgr8')
                out.color_encoding = 'bgr8'
            if mono:
                out.mono = cvtColor2(out.raw, raw_encoding, 'mono8')
        elif raw_encoding.find('mono') != -1:
            if mono:
                out.mono = out.raw
            if color:
                raise Exception('cant get color from mono image')
        else:  # Otherwise assume color
            if mono:
                out.mono = cvtColor2(out.raw, raw_encoding, 'mono8')
            if color:
                out.color = out.raw
                out.color_encoding = raw_encoding
        if flags & ImageProc.RECT:
            if out.rect is None:
                out.rect = np.zeros(out.mono.shape)
            model.rectifyImage(out.mono, out.rect)
        if flags & ImageProc.RECT_COLOR:
            if out.rect_color is None:
                out.rect_color = np.zeros(out.color.shape, out.color.dtype)
            model.rectifyImage(out.color, out.rect_color)
예제 #3
0
    def imgmsg_to_cv2(self, img_msg, desired_encoding = "passthrough"):
        """
        Convert a sensor_msgs::Image message to an OpenCV :ctype:`cv::Mat`.

        :param img_msg:   A sensor_msgs::Image message
        :param desired_encoding:  The encoding of the image data, one of the following strings:

           * ``"passthrough"``
           * one of the standard strings in sensor_msgs/image_encodings.h

        :rtype: :ctype:`cv::Mat`
        :raises CvBridgeError: when conversion is not possible.

        If desired_encoding is ``"passthrough"``, then the returned image has the same format as img_msg.
        Otherwise desired_encoding must be one of the standard image encodings

        This function returns an OpenCV :ctype:`cv::Mat` message on success, or raises :exc:`cv_bridge.CvBridgeError` on failure.
        """
        import cv2
        import numpy as np
        dtype, n_channels = self.encoding_to_dtype_with_channels(img_msg.encoding)
        im = np.ndarray(shape=(img_msg.height, img_msg.width, n_channels),
                           dtype=dtype, buffer=img_msg.data)

        if desired_encoding == "passthrough":
            return im

        from cv_bridge.boost.cv_bridge_boost import cvtColor2

        try:
            res = cvtColor2(im, img_msg.encoding, desired_encoding)
        except RuntimeError as e:
            raise CvBridgeError(e)

        return res
예제 #4
0
파일: bag_utils.py 프로젝트: subokita/pybot
def compressed_imgmsg_to_cv2(cmprs_img_msg, desired_encoding="passthrough"):
    """
    Convert a sensor_msgs::CompressedImage message to an OpenCV :cpp:type:`cv::Mat`.

    :param cmprs_img_msg:   A :cpp:type:`sensor_msgs::CompressedImage` message
    :param desired_encoding:  The encoding of the image data, one of the following strings:

       * ``"passthrough"``
       * one of the standard strings in sensor_msgs/image_encodings.h

    :rtype: :cpp:type:`cv::Mat`
    :raises CvBridgeError: when conversion is not possible.

    If desired_encoding is ``"passthrough"``, then the returned image has the same format as img_msg.
    Otherwise desired_encoding must be one of the standard image encodings

    This function returns an OpenCV :cpp:type:`cv::Mat` message on success, or raises :exc:`cv_bridge.CvBridgeError` on failure.

    If the image only has one channel, the shape has size 2 (width and height)
    """
    str_msg = cmprs_img_msg.data
    buf = np.ndarray(shape=(1, len(str_msg)),
                     dtype=np.uint8,
                     buffer=cmprs_img_msg.data)
    im = cv2.imdecode(buf, cv2.IMREAD_ANYCOLOR)

    if desired_encoding == "passthrough":
        return im

    try:
        res = cvtColor2(im, "bgr8", desired_encoding)
    except RuntimeError as e:
        raise CvBridgeError(e)

    return res
예제 #5
0
    def process(self, args, images):
        dir = Path(args.dir)
        image_bridge = CvBridge()
        idx = 0

        dir.mkdir(parents=True, exist_ok=True)
        for topic, img_msg, t in images:
            img = image_bridge.imgmsg_to_cv2(img_msg)
            if args.encoding != 'passthrough':
                if img_msg.encoding.startswith('bayer_') and args.demosaicing:
                    # use custom debayering
                    # cvtColor2 unfortunately doesn't expose a demosaicing algorithm parameter
                    conv_code = conversion_code(
                        img_msg.encoding, args.encoding, args.demosaicing)
                    img = cv.cvtColor(img, conv_code)
                else:
                    try:
                        img = cvtColor2(img, img_msg.encoding, args.encoding)
                    except RuntimeError as e:
                        raise CvBridgeError(e)

            tpc_path = topic.lstrip('/').replace('/', '_')
            filename = args.name.replace('%tpc', tpc_path)
            filename = filename.replace('%t', str(t))
            filename = filename.replace('%i', str(idx).zfill(8))
            img_path = dir / filename
            cv.imwrite(str(img_path), img)
            idx += 1
예제 #6
0
    def imgmsg_to_cv2(self, img_msg, desired_encoding="passthrough"):
        """
        Convert a sensor_msgs::Image message to an OpenCV :cpp:type:`cv::Mat`.

        :param img_msg:   A :cpp:type:`sensor_msgs::Image` message
        :param desired_encoding:  The encoding of the image data, one of the following strings:

           * ``"passthrough"``
           * one of the standard strings in sensor_msgs/image_encodings.h

        :rtype: :cpp:type:`cv::Mat`
        :raises CvBridgeError: when conversion is not possible.

        If desired_encoding is ``"passthrough"``, then the returned image has the same format as img_msg.
        Otherwise desired_encoding must be one of the standard image encodings

        This function returns an OpenCV :cpp:type:`cv::Mat` message on success, or raises :exc:`cv_bridge.CvBridgeError` on failure.

        If the image only has one channel, the shape has size 2 (width and height)
        """
        import cv2
        import numpy as np
        if img_msg.encoding == '32FC1':
            dtype = 'float32'
            n_channels = 1
        elif img_msg.encoding == '32FC4':
            dtype = 'float32'
            n_channels = 4
        elif img_msg.encoding == '8UC4':
            dtype = 'uint8'
            n_channels = 4
        else:
            dtype, n_channels = self.encoding_to_dtype_with_channels(
                img_msg.encoding)
        dtype = np.dtype(dtype)
        dtype = dtype.newbyteorder('>' if img_msg.is_bigendian else '<')
        if n_channels == 1:
            im = np.ndarray(shape=(img_msg.height, img_msg.width),
                            dtype=dtype,
                            buffer=img_msg.data)
        else:
            im = np.ndarray(shape=(img_msg.height, img_msg.width, n_channels),
                            dtype=dtype,
                            buffer=img_msg.data)
        # If the byt order is different between the message and the system.
        if img_msg.is_bigendian == (sys.byteorder == 'little'):
            im = im.byteswap().newbyteorder()

        if desired_encoding == "passthrough":
            return im

        from cv_bridge.boost.cv_bridge_boost import cvtColor2

        try:
            res = cvtColor2(im, img_msg.encoding, desired_encoding)
        except RuntimeError as e:
            raise CvBridgeError(e)

        return res
예제 #7
0
파일: core.py 프로젝트: fqez/common
    def imgmsg_to_cv2(self, img_msg, desired_encoding = "passthrough"):
        """
        Convert a sensor_msgs::Image message to an OpenCV :cpp:type:`cv::Mat`.

        :param img_msg:   A :cpp:type:`sensor_msgs::Image` message
        :param desired_encoding:  The encoding of the image data, one of the following strings:

           * ``"passthrough"``
           * one of the standard strings in sensor_msgs/image_encodings.h

        :rtype: :cpp:type:`cv::Mat`
        :raises CvBridgeError: when conversion is not possible.

        If desired_encoding is ``"passthrough"``, then the returned image has the same format as img_msg.
        Otherwise desired_encoding must be one of the standard image encodings

        This function returns an OpenCV :cpp:type:`cv::Mat` message on success, or raises :exc:`cv_bridge.CvBridgeError` on failure.

        If the image only has one channel, the shape has size 2 (width and height)
        """
        import cv2
        import numpy as np
        dtype, n_channels = self.encoding_to_dtype_with_channels(img_msg.encoding)
        dtype = np.dtype(dtype)
        dtype = dtype.newbyteorder('>' if img_msg.is_bigendian else '<')
        if n_channels == 1:
            im = np.ndarray(shape=(img_msg.height, img_msg.width),
                           dtype=dtype, buffer=img_msg.data)
        else:
            im = np.ndarray(shape=(img_msg.height, img_msg.width, n_channels),
                           dtype=dtype, buffer=img_msg.data)
        # If the byt order is different between the message and the system.
        if img_msg.is_bigendian == (sys.byteorder == 'little'):
            im = im.byteswap().newbyteorder()

        if desired_encoding == "passthrough":
            return im

        from cv_bridge.boost.cv_bridge_boost import cvtColor2

        try:
            res = cvtColor2(im, img_msg.encoding, desired_encoding)
        except RuntimeError as e:
            raise CvBridgeError(e)

        return res
예제 #8
0
파일: core.py 프로젝트: fqez/common
    def compressed_imgmsg_to_cv2(self, cmprs_img_msg, desired_encoding = "passthrough"):
        """
        Convert a sensor_msgs::CompressedImage message to an OpenCV :cpp:type:`cv::Mat`.

        :param cmprs_img_msg:   A :cpp:type:`sensor_msgs::CompressedImage` message
        :param desired_encoding:  The encoding of the image data, one of the following strings:

           * ``"passthrough"``
           * one of the standard strings in sensor_msgs/image_encodings.h

        :rtype: :cpp:type:`cv::Mat`
        :raises CvBridgeError: when conversion is not possible.

        If desired_encoding is ``"passthrough"``, then the returned image has the same format as img_msg.
        Otherwise desired_encoding must be one of the standard image encodings

        This function returns an OpenCV :cpp:type:`cv::Mat` message on success, or raises :exc:`cv_bridge.CvBridgeError` on failure.

        If the image only has one channel, the shape has size 2 (width and height)
        """
        import cv2
        import numpy as np

        str_msg = cmprs_img_msg.data
        buf = np.ndarray(shape=(1, len(str_msg)),
                          dtype=np.uint8, buffer=cmprs_img_msg.data)
        im = cv2.imdecode(buf, cv2.IMREAD_ANYCOLOR)

        if desired_encoding == "passthrough":
            return im

        from cv_bridge.boost.cv_bridge_boost import cvtColor2

        try:
            res = cvtColor2(im, "bgr8", desired_encoding)
        except RuntimeError as e:
            raise CvBridgeError(e)

        return res