我正在从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
转换为灰度的图像如下所示:
答案 0 :(得分:19)
我今天遇到了同样的问题。最后,我比较了三种方法:
//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。
我的输入文件是jpgs,因此可能存在与您的特定图像格式相关的问题。
答案 1 :(得分:10)
简单的答案是,openCV函数使用BGR格式。如果您使用imread
或VideoCapture
读取图片,则该图片将始终为BGR。如果使用RGB2GRAY,则将蓝色通道与绿色互换。获得亮度的公式是
y = 0.587*green + 0.299*red + 0.114*blue
所以如果你改变绿色和蓝色,这将导致巨大的计算错误。
迎接
答案 2 :(得分:1)
我曾经遇到类似的问题,使用OpenGL着色器。似乎OpenCV读取您的图像的第一个容器不支持所有颜色范围,因此您看到图像是一个较差的灰度转换。但是,使用cvtColor将原始图像转换为灰度后,容器与第一个不同,并支持所有范围。在我看来,第一个使用少于8位的灰度或更改为灰度使用坏方法。但是由于灰色通道中有更多的比特,第二个给出了平滑的图像。