Python 为什么 cv2.imwrite() 会改变图片的颜色?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42406338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
why cv2.imwrite() changes the color of pics?
提问by StalkerMuse
I have the following piece of code:
我有以下一段代码:
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])
The size of picture is 512*512, after being saved, a blue picture turns yellow. It seems that a channel is abandoned. I really don't know why.
图片大小为512*512,保存后蓝色图片变为黄色。似乎放弃了一个频道。我真的不知道为什么。
Here is the value of current_img:
这是 current_img 的值:
回答by Dan Ma?ek
Your problem is in the fact that skimage.io.imread
loads image as RGB (or RGBA), but OpenCV assumes the image to be BGR or BGRA(BGR is the default OpenCV colour format). This means that blue and red planes get flipped.
您的问题在于skimage.io.imread
将图像加载为 RGB(或 RGBA),但 OpenCV 假定图像为BGR 或 BGRA(BGR 是默认的 OpenCV 颜色格式)。这意味着蓝色和红色平面被翻转。
3 Channel Images
3 通道图像
Let's try this out with the following simple test image:
让我们用以下简单的测试图像来试试这个:
First let's try your original algorithm:
首先让我们试试你的原始算法:
import skimage.io
import cv2
img = skimage.io.imread('sample.png')
cv2.imwrite('sample_out_1.png', img)
We get the following result:
我们得到以下结果:
As you can see, red and blue channels are visibly swapped.
如您所见,红色和蓝色通道明显交换。
The first approach, assuming you want to still use skimage to read and cv2 to write is to use cv2.cvtColor
to convert from RGB to BGR.
第一种方法,假设您仍然想使用skimage读取和cv2写入,则使用cv2.cvtColor
从RGB转换为BGR。
Since the new OpenCV docs don't mention Python syntax, in this case you can also use the appropriate reference for 2.4.x.
由于新的 OpenCV 文档没有提到 Python 语法,在这种情况下,您还可以使用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))
Now we get the following output:
现在我们得到以下输出:
An alternative is to just use OpenCV -- use cv2.imread
to load the image. In this case we're working only with BGR images.
另一种方法是仅使用 OpenCV——cv2.imread
用于加载图像。在这种情况下,我们仅使用 BGR 图像。
NB:Not providing any flags means cv2.IMREAD_COLOR
is used by default -- i.e. image is always loaded as a 3-channel image (dropping any potential alpha channels).
注意:cv2.IMREAD_COLOR
默认情况下使用不提供任何标志的方式——即图像始终作为 3 通道图像加载(删除任何潜在的 alpha 通道)。
import cv2
img = cv2.imread('sample.png')
cv2.imwrite('sample_out_3.png', img)
4 Channel Images
4 通道图像
From your screenshot, it appears that you have a 4 channel image. This would mean RGBA in skimage, and BGRA in OpenCV. The principles would be similar.
从您的屏幕截图来看,您似乎有一张 4 通道图像。这意味着 skimage 中的 RGBA 和 OpenCV 中的 BGRA。原则是相似的。
- Either use colour conversion code
cv2.COLOR_RGBA2BGRA
- Or use
cv2.imread
with flagcv2.IMREAD_UNCHANGED
- 要么使用颜色转换代码
cv2.COLOR_RGBA2BGRA
- 或
cv2.imread
与标志一起使用cv2.IMREAD_UNCHANGED
回答by anms_pro
The image on input (as a png) is in RGB order but the image in memory (as a cv::Mat) is in BGR order.
Use cv2.imread()
for input. So, imread() will internally convert from rgb to bgr and imwrite() will do the opposite, all under the hood.
输入上的图像(作为 png)按 RGB 顺序排列,但内存中的图像(作为 cv::Mat)按 BGR 顺序排列。使用cv2.imread()
输入。因此, imread() 将在内部从 rgb 转换为 bgr 而 imwrite() 将执行相反的操作,所有这些都在幕后。
Here's how you do it:
以下是您的操作方法:
current_img = cv2.imread('/home/chipin/heart/tray.png')
cv2.imwrite('/home/chipin/heart/01.png', current_img)