OpenCV imread() 尽管设置了颜色标志,为什么会返回灰度图像?

huangapple go评论69阅读模式
英文:

Why does OpenCV imread() return grayscale images, despite color flag?

问题

我使用openCV的imread()读取了一个jp2文件
图像加载成功,但总是灰度图。

我在文档中看到,一些IMREAD_FLAGS可能导致这种情况,而且我也知道cv2可能会改变通道顺序为BGR。

然而,我认为这些原因都不是问题所在。我使用不同的IMREAD_FLAGS导入了图像,并保存了副本,如下所示:

image = cv2.imread("mypath.jp2", cv2.IMREAD_UNCHANGED) # 在这里更改标志
cv2.imwrite("IMREAD_UNCHANGED.png", image) # 更改文件名

我还使用cv2.cvtColor(image, cv2.COLOR_BGR2RGB)将图像转换为RGB。结果图像尺寸不同,但结果始终是灰度图像:

OpenCV imread() 尽管设置了颜色标志,为什么会返回灰度图像?

此外,我可以确定这些图像是彩色的,因为使用Pillow打开它后,它看起来是这样的:

OpenCV imread() 尽管设置了颜色标志,为什么会返回灰度图像?

有人能告诉我我在这里做错了什么吗?提前感谢!

英文:

I'm reading an jp2 file using openCV's imread().
The image loads, but it's always grayscale.

I saw in the documentation that some IMREAD_FLAGS could cause this and I also know that cv2 may change the channel order to BGR.

However, I believe none of these reasons are the issue here. I imported the image with different IMREAD_FLAGS and saved copies like this:

image = cv2.imread("mypath.jp2", cv2.IMREAD_UNCHANGED) # change flag here
cv2.imwrite("IMREAD_UNCHANGED.png", image) # change file name accordingly

I also converted the image to RGB using cv2.cvtColor(image,cv2.COLOR_BGR2RGB). The resulting image sizes are different, but the result are always a grayscale image:

OpenCV imread() 尽管设置了颜色标志,为什么会返回灰度图像?

Also, I'm certain these images have color, because when opening it with Pillow it looks like this:

OpenCV imread() 尽管设置了颜色标志,为什么会返回灰度图像?

Can someone tell me what I'm doing wrong here? Thanks in advance !

答案1

得分: 1

使用cv.imread(path)(在Windows上的OpenCV 4.7.0版本)时,它返回三个通道,而不是灰度。我没有检查OpenCV是否删除了任何颜色信息。

如果我要求IMREAD_UNCHANGED,它会报错:

> [ERROR:0@171.019] global grfmt_jpeg2000_openjpeg.cpp:410 cv::`anonymous-namespace'::decodeGrayscaleData OpenJPEG2000:不支持将4个分量转换为4个用于灰度图像解码

对于cv.imreadmulti(path, flags=cv.IMREAD_UNCHANGED),通常是多平面图像格式(TIFF可以是这样)的正确选择,会出现相同的错误。如果不使用标志,它只返回3通道数据的一个图层。

因此,这可能会导致一个bug报告。如果你想提出报告,请在OpenCV的GitHub上提出。

PIL将其读取为"RGBA"。那里没有透明度,只是第四个通道。

文件名包含"rgbi",这让我怀疑它是一个多层文件,或者至少第四通道包含另一种颜色层,而不是"透明度"。

如果你从PIL图像转换为NumPy数组,至少你可以获得所有通道和它们的数据。

import numpy as np
from PIL import Image

im = Image.open(path)
im = np.asarray(im)

你还可以使用imageio。它会警告图像很大,但它会加载整个图像。这是一个复杂的库,所以请查看文档以了解推荐的读取此类文件的方法。

import imageio

im = imageio.read(path)
im.get_data(0) # (10000, 10000, 4)
英文:

When I use cv.imread(path) (OpenCV 4.7.0 on Windows), it gives me three channels, not grayscale. I didn't look to check if OpenCV removed any color information.

It does complain if I ask for IMREAD_UNCHANGED:

> [ERROR:0@171.019] global grfmt_jpeg2000_openjpeg.cpp:410 cv::`anonymous-namespace'::decodeGrayscaleData OpenJPEG2000: unsupported conversion from 4 components to 4 for Grayscale image decoding

The same error happens for cv.imreadmulti(path, flags=cv.IMREAD_UNCHANGED) which is usually the right choice for multi-plane image formats (TIFF can be like that). Without the flag, it just returns one layer of 3-channel data.

So there's potential for a bug report. If you want to file it, do it on OpenCV's github.

PIL reads it as "RGBA". There is no transparency there, it's just a 4th channel.

The file name contains "rgbi", which makes me suspect it's a multi-layer file, or at least the fourth channel contains another color layer, not "transparency".

If you convert from PIL Image to numpy array, at least you can get all the channels and their data.

import numpy as np
from PIL import Image

im = Image.open(path)
im = np.asarray(im)

You could also use imageio. It warns about the image being huge, but it does load the whole thing. It's a complex library, so check the docs for recommended ways to read such files.

import imageio

im = imageio.read(path)
im.get_data(0) # (10000, 10000, 4)

huangapple
  • 本文由 发表于 2023年4月7日 02:51:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75952834.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定