【ROS-Error】 Can't convert image: local variable ‘pil_mode‘ referenced before assignment
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