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

Posted

技术标签:

【中文标题】为啥 cv2.imwrite() 会改变图片的颜色?【英文标题】:why cv2.imwrite() changes the color of pics?为什么 cv2.imwrite() 会改变图片的颜色? 【发布时间】:2017-07-13 09:05:32 【问题描述】:

我有以下代码:

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的值:

【问题讨论】:

我认为io.imread 是来自 skimage 的那个? 如果是这样,那么问题在于skimage.io.imread 将图像加载为 RGB,但 numpy 假定图像为BGR。这意味着蓝色和红色平面被翻转。为什么不直接使用cv2.imread 来加载图片呢? 谢谢,我想是这样。请问我该如何纠正? 要么使用cv2.imread,它也会以BGR格式读取(这是OpenCV的默认设置),或者使用cv2.cvtColor从RGB转换为BGR。 哦,最后一个全是零的通道——看起来像透明的。在这种情况下,它是 RGBA BGRA。 【参考方案1】:

输入上的图像(作为 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)  

【讨论】:

【参考方案2】:

您的问题在于skimage.io.imread 将图像加载为 RGB(或 RGBA),但 OpenCV 假定图像为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

【讨论】:

嗯,也许我不应该让示例图像旋转对称。 :) 发现这很有用,因为我用cv2.imread 阅读但用matplotlib 显示。虽然 opencv 使用 BGR,但我觉得很奇怪。 好的,请阅读:learnopencv.com/why-does-opencv-use-bgr-color-format。显然 OpenCV 使用 BGR 是因为马屁。 @DanMašek 解释得很好。谢谢。

以上是关于为啥 cv2.imwrite() 会改变图片的颜色?的主要内容,如果未能解决你的问题,请参考以下文章

cv2 imwrite 和德语字母(“ä, ü, ö”)

OpenCV 函数学习02-图像的保存(cv2.imwrite)

CV2(cv2.imwrite)- Python 不断抛出“断言失败”错误

Python+OpenCV:cv2.imwrite

cv2.waitKey(25) & 0xFF == ord('q'): 和 cv2.imwrite() 不工作

cv2.imwrite() 没有将时间戳写入帧