Python中cv2.imwrite保存RGB图像后用PIL读取颜色反转问题求助
问题:OpenCV与PIL图像颜色格式兼容问题
我对OpenCV在Python中的工作逻辑有困惑。我知道cv2.imread()默认按BGR格式读取图像,但用cv2.cvtColor(image, cv2.COLOR_BGR2RGB)转成RGB后,用cv2.imwrite()保存,再用PIL读取时出现颜色反转的问题。
背景:我正在搭建ROS管道,需要通过OpenCV ROS桥获取图像话题,之后用PIL处理图像。
参考代码如下:
import numpy as np import cv2 from matplotlib import pyplot as plt from PIL import Image as im image1 = cv2.imread('/home/ali/Pictures/rgb.png' ) image2 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB) cv2.imwrite('/home/ali/Pictures/test_img_bgr_cv.png', image2) image3 = im.open('/home/ali/Pictures/test_img_bgr_cv.png') plt.figure(figsize=(10, 10)) plt.subplot(1, 3, 1), plt.imshow(image1) plt.title('Image 1'), plt.xticks([]), plt.yticks([]) plt.subplot(1, 3, 2), plt.imshow(image2) plt.title('Image 2'), plt.xticks([]), plt.yticks([]) plt.subplot(1,3,3), plt.imshow(image3) plt.title('Image 3'), plt.xticks([]), plt.yticks([]) plt.show()
问题原因
核心问题出在cv2.imwrite()的行为上——它始终以BGR格式写入图像文件,不管传入的数组是RGB还是BGR。也就是说,当你把转好的RGB数组传给cv2.imwrite()时,它会把这个数组当作BGR来编码保存,相当于隐式做了一次RGB→BGR转换。而PIL的im.open()会按标准RGB格式解析文件,自然就出现了颜色反转(BGR被当成RGB显示)。
解决方案
1. 直接转换格式(无需保存文件)
如果不需要中间保存文件,直接把OpenCV的RGB数组转成PIL图像,一步到位:
# image2是OpenCV转好的RGB数组 pil_image = im.fromarray(image2)
这种方式避免了文件读写的格式干扰,适合ROS管道中的实时处理场景。
2. 必须保存文件时的两种正确做法
- 方式一:转回BGR后用OpenCV保存
把RGB数组转回BGR,让cv2.imwrite()写入正确的色彩数据,PIL读取时会自动按RGB解析:
# 将RGB转回BGR再保存 cv2.imwrite('/home/ali/Pictures/test_img_bgr_cv.png', cv2.cvtColor(image2, cv2.COLOR_RGB2BGR)) # PIL读取后正常显示 image3 = im.open('/home/ali/Pictures/test_img_bgr_cv.png')
- 方式二:用PIL保存RGB数组
跳过OpenCV的写入逻辑,直接用PIL保存转好的RGB数组:
# 把OpenCV的RGB数组转成PIL图像再保存 pil_image = im.fromarray(image2) pil_image.save('/home/ali/Pictures/test_img_pil.png') # 读取时直接正常显示 image3 = im.open('/home/ali/Pictures/test_img_pil.png')
ROS场景建议
在ROS管道中,通过OpenCV桥获取的图像本身就是BGR格式,后续要交给PIL处理时,最高效的方式是直接将BGR转RGB后用im.fromarray()转换为PIL图像,跳过中间文件保存步骤,减少格式转换的出错概率。
内容的提问来源于stack exchange,提问作者robo1996
相关产品推荐
相关产品推荐

