使用imread将OpenCV图像从RGB转换为灰度,结果不佳

使用imread将OpenCV图像从RGB转换为灰度,结果不佳,opencv,Opencv,我正在将PNG文件中的24位RGB图像加载到我的OpenCV应用程序中 但是,直接使用imread将图像加载为灰度会产生非常糟糕的结果 Mat src1 = imread(inputImageFilename1.c_str(), 0); 将RGB图像加载为RGB并将其转换为灰度,可以获得更好的效果 Mat src1 = imread(inputImageFilename1.c_str(), 1); cvtColor(src1, src1Gray, CV_RGB2GRAY); 我想知道我是否正

我正在将PNG文件中的24位RGB图像加载到我的OpenCV应用程序中

但是,直接使用
imread
将图像加载为灰度会产生非常糟糕的结果

Mat src1 = imread(inputImageFilename1.c_str(), 0);
将RGB图像加载为RGB并将其转换为灰度,可以获得更好的效果

Mat src1 = imread(inputImageFilename1.c_str(), 1);
cvtColor(src1, src1Gray, CV_RGB2GRAY);
我想知道我是否正确地将
imread
用于图像类型。有没有人经历过类似的行为

使用
imread
转换为灰度的图像如下所示:

使用
cvtColor
转换为灰度的图像如下所示:

我曾经遇到过类似的问题,使用OpenGL着色器。OpenCV读取图像时使用的第一个容器似乎不支持所有颜色范围,因此您会发现图像的灰度变换效果不佳。但是,使用cvtColor将原始图像转换为灰度后,容器与第一个容器不同,并且支持所有范围。在我看来,第一个使用少于8位的灰度或改变为灰度使用了一个糟糕的方法。但第二张照片图像平滑,因为灰色通道中有更多的比特。

我今天也遇到了同样的问题。最后,我比较了三种方法:

//method 1
cv::Mat gs = cv::imread(filename, CV_LOAD_IMAGE_GRAYSCALE);

//method 2
cv::Mat color = cv::imread(filename, 1); //loads color if it is available
cv::Mat gs_rgb(color.size(), CV_8UC1);
cv::cvtColor(color, gs_rgb, CV_RGB2GRAY);

//method 3
cv::Mat gs_bgr(color.size(), CV_8UC1);
cv::cvtColor(color, gs_bgr, CV_BGR2GRAY);
方法1(加载灰度)和方法3(CV_BGR2GRAY)产生相同的结果,而方法2产生不同的结果。为了我自己的目的,我开始使用CV_BGR2GRAY


我的输入文件是JPG,因此可能存在与特定图像格式相关的问题

简单的答案是,openCV函数使用BGR格式。如果您使用
imread
VideoCapture
读取图像,它将始终是BGR。如果使用RGB2GRAY,则将蓝色通道与绿色通道交换。得到亮度的公式是

y = 0.587*green + 0.299*red + 0.114*blue
因此,如果您更改绿色和蓝色,这将导致巨大的计算错误


问候

“彩色”图像在OpenCV中表示BGR。所以第二个版本的代码是不正确的。它应该使用
CV\u bgr2 gray
进行颜色转换。感谢您的评论。我尝试使用CV_BGR2GRAY而不是CV_RGB2GRAY将图像转换为灰度,但得到了相同的结果。您也可以附加您的原始图像吗?不幸的是,以我目前的声誉,我无法将图像发布到我的帖子中。此外,有一个限制,以我的声誉内的帖子2超链接。谢谢你的提示。原始图像位于此处:您是否找到支持此推理的文档?面对一个类似的问题&我倾向于相信这可能是事实,但在我的推理中找不到任何结论。事实就是这样,因为帧缓冲区包含每种颜色255的范围,也包含单色光谱255的范围。您需要浮点来支持更好的范围。Opencv imread以BGR格式返回图像,因此我认为正确的灰度转换为CV_BGR2GRAY,正如您在第三种方法中提到的那样,它不是也交换了红色通道吗?在这种情况下,将给定的
BGR
解释为
RGB
,从而导致(实际的)
B
被错误地解释为
R
,而
R
被错误地解释为
B
?因此,根据您的回答,修复方法是将
cvtColor
调用中的
CV\u RGB2GRAY
替换为
CV\u BGR2GRAY