为什么 cv2.imwrite() 会改变图片的颜色?

why cv2.imwrite() changes the color of pics?

我有如下一段代码:

imgs = glob.glob('/home/chipin/heart/tray.png')
current_img = io.imread(imgs[0])
cv2.imwrite('/home/chipin/heart/01.png', current_img[0:511,0:511])  

图片大小为512*512,保存后蓝色的图片变黄了。好像一个通道被废弃了。我真的不知道为什么。

这里是current_img的值:

您的问题在于 skimage.io.imread loads image as RGB (or RGBA), but OpenCV assumes the image to be BGR or BGRA(BGR 是默认的 OpenCV 颜色格式)。这意味着蓝色和红色平面被翻转。


3 通道图像

让我们用下面的简单测试图像来试试看:


首先让我们试试你原来的算法:

import skimage.io
import cv2

img = skimage.io.imread('sample.png')
cv2.imwrite('sample_out_1.png', img)

我们得到以下结果:

如您所见,红色和蓝色通道明显交换了。


第一种方法,假设您仍想使用 skimage 读取和 cv2 写入,是使用 cv2.cvtColor 将 RGB 转换为 BGR。

因为新的 OpenCV 文档没有提到 Python 语法,在这种情况下你也可以使用 appropriate reference for 2.4.x.

import skimage.io
import cv2

img = skimage.io.imread('sample.png')
cv2.imwrite('sample_out_2.png', cv2.cvtColor(img, cv2.COLOR_RGB2BGR))    

现在我们得到以下输出:


另一种方法是只使用 OpenCV——使用 cv2.imread 加载图像。在这种情况下,我们仅使用 BGR 图像。

注意: 不提供任何标志意味着默认使用 cv2.IMREAD_COLOR——即图像总是作为 3 通道图像加载(删除任何潜在的 alpha 通道).

import cv2

img = cv2.imread('sample.png')
cv2.imwrite('sample_out_3.png', img)


4 通道图像

从您的屏幕截图来看,您似乎有一张 4 通道图像。这意味着 skimage 中的 RGBA 和 OpenCV 中的 BGRA。原则应该是相似的。

  • 要么使用颜色转换代码cv2.COLOR_RGBA2BGRA
  • 或使用 cv2.imread 标志 cv2.IMREAD_UNCHANGED

输入图像(作为 png)是 RGB 顺序,但内存中的图像(作为 cv::Mat)是 BGR 顺序。 使用 cv2.imread() 输入。因此,imread() 将在内部从 rgb 转换为 bgr,而 imwrite() 将做相反的事情,所有这些都在幕后。

操作方法如下:

current_img = cv2.imread('/home/chipin/heart/tray.png')
cv2.imwrite('/home/chipin/heart/01.png', current_img)