rqt_bag ***.bag 报错:

Can’t convert image: local variable ‘pil_mode’ referenced before assignment

 

原因: 源于rqt_bag工具中存在bug,pil_mode 被定义为局部变量,但却在全局中被使用。

如何查找原因:

1. 首先查找rqt_bag: find / -name rqt_bag

/opt/ros/kinetic/lib/python2.7/dist-packages/rqt_bag

2. cd /opt/ros/kinetic/lib/python2.7/dist-packages/rqt_bag

3. 查找 pil_mode 变量:grep -rn pil_mode

rqt_bag_plugins/image_helper.py:57:            pil_mode = ‘RGB’
rqt_bag_plugins/image_helper.py:67:                pil_mode = ‘I;16’
rqt_bag_plugins/image_helper.py:73:                pil_mode = ‘F’
rqt_bag_plugins/image_helper.py:87:                pil_mode, (img_msg.width, img_msg.height), img_msg.data, ‘raw’, mode, 0, 1)
rqt_bag_plugins/image_helper.py:90:        if pil_mode == ‘I;16’:

4. 修改源码

修改前

def imgmsg_to_pil(img_msg, rgba=True):
    try:
        if img_msg._type == 'sensor_msgs/CompressedImage':
            pil_img = Image.open(StringIO(img_msg.data))
            if pil_img.mode != 'L':
                pil_img = pil_bgr2rgb(pil_img)
        else:
            pil_mode = 'RGB'
            alpha = False
            if img_msg.encoding == 'mono8':
                mode = 'L'
            elif img_msg.encoding == 'rgb8':
                mode = 'RGB'
            elif img_msg.encoding == 'bgr8':
                mode = 'BGR'
            elif img_msg.encoding in ['bayer_rggb8', 'bayer_bggr8', 'bayer_gbrg8', 'bayer_grbg8']:
                mode = 'L'
            elif img_msg.encoding in ['bayer_rggb16', 'bayer_bggr16', 'bayer_gbrg16', 'bayer_grbg16']:
                pil_mode = 'I;16'
                if img_msg.is_bigendian:
                    mode='I;16B'
                else:
                    mode='I;16L'
            elif img_msg.encoding == 'mono16' or img_msg.encoding == '16UC1':
                pil_mode = 'F'
                if img_msg.is_bigendian:
                    mode = 'F;16B'
                else:
                    mode = 'F;16'
            elif img_msg.encoding == 'rgba8':
                mode = 'BGR'
                alpha = True
            elif img_msg.encoding == 'bgra8':
                mode = 'RGB'
                alpha = True
            else:
                raise Exception("Unsupported image format: %s" % img_msg.encoding)
            pil_img = Image.frombuffer(
                pil_mode, (img_msg.width, img_msg.height), img_msg.data, 'raw', mode, 0, 1)
        # 16 bits conversion to 8 bits
        if pil_mode == 'I;16':
            pil_img = pil_img.convert('I').point(lambda i: i * (1. / 256.)).convert('L')
        if pil_img.mode == 'F':
            pil_img = pil_img.point(lambda i: i * (1. / 256.)).convert('L')
            pil_img = ImageOps.autocontrast(pil_img)

        if rgba and pil_img.mode != 'RGBA':
            pil_img = pil_img.convert('RGBA')

        return pil_img

    except Exception as ex:
        print('Can\'t convert image: %s' % ex, file=sys.stderr)
        return None

修改后

def imgmsg_to_pil(img_msg, rgba=True):
    try:
        pil_mode = 'RGB'
        if img_msg._type == 'sensor_msgs/CompressedImage':
            pil_img = Image.open(StringIO(img_msg.data))
            if pil_img.mode != 'L':
                pil_img = pil_bgr2rgb(pil_img)
        else:
            alpha = False
            if img_msg.encoding == 'mono8':
                mode = 'L'
            elif img_msg.encoding == 'rgb8':
                mode = 'RGB'
            elif img_msg.encoding == 'bgr8':
                mode = 'BGR'
            elif img_msg.encoding in ['bayer_rggb8', 'bayer_bggr8', 'bayer_gbrg8', 'bayer_grbg8']:
                mode = 'L'
            elif img_msg.encoding in ['bayer_rggb16', 'bayer_bggr16', 'bayer_gbrg16', 'bayer_grbg16']:
                pil_mode = 'I;16'
                if img_msg.is_bigendian:
                    mode='I;16B'
                else:
                    mode='I;16L'
            elif img_msg.encoding == 'mono16' or img_msg.encoding == '16UC1':
                pil_mode = 'F'
                if img_msg.is_bigendian:
                    mode = 'F;16B'
                else:
                    mode = 'F;16'
            elif img_msg.encoding == 'rgba8':
                mode = 'BGR'
                alpha = True
            elif img_msg.encoding == 'bgra8':
                mode = 'RGB'
                alpha = True
            else:
                raise Exception("Unsupported image format: %s" % img_msg.encoding)
            pil_img = Image.frombuffer(
                pil_mode, (img_msg.width, img_msg.height), img_msg.data, 'raw', mode, 0, 1)
        # 16 bits conversion to 8 bits
        if pil_mode == 'I;16':
            pil_img = pil_img.convert('I').point(lambda i: i * (1. / 256.)).convert('L')
        if pil_img.mode == 'F':
            pil_img = pil_img.point(lambda i: i * (1. / 256.)).convert('L')
            pil_img = ImageOps.autocontrast(pil_img)

        if rgba and pil_img.mode != 'RGBA':
            pil_img = pil_img.convert('RGBA')

        return pil_img

    except Exception as ex:
        print('Can\'t convert image: %s' % ex, file=sys.stderr)
        return None

 

本文地址:https://blog.csdn.net/lgh0824/article/details/110373697