OpenCV图像从RGB到HSV的转换

10

当我在一张样本图片(RGB)上运行以下代码,并将其处理以显示转换后的HSV图像时,两者似乎是不同的...

有人能解释一下为什么会出现这种情况吗?
或者
你能提供一个解决方案吗,使它们不再产生差异...毕竟它们是同一张图片

Mat img_hsv,img_rgb,red_blob,blue_blob;
img_rgb = imread("pic.png",1);
cvtColor(img_rgb,img_hsv,CV_RGB2HSV);
namedWindow("win1", CV_WINDOW_AUTOSIZE);
imshow("win1", img_hsv);

你需要将 HSV 图像转换回 BGR,以便使用 imshow() 显示它。 - smwikipedia
3个回答

28
  1. 我对新的(2.x)OpenCV还不够熟悉,但通常在OpenCV中加载的图像采用的是CV_BGR通道顺序,而不是RGB,因此您最可能需要使用CV_BGR2HSV。

  2. OpenCV实际上并不“知道”HSV,它只会在第一个通道中编码色调(Hue),第二个通道中编码饱和度(Saturation),第三个通道中编码明度(Value)。如果您在OpenCV中显示图像,highgui会假设它是BGR图像,因此将第一个通道(现在是色调)解释为蓝色等。


即使我也尝试了那个,兄弟...也没用...输出图像只有一点点微小的变化...它难道不是使用以下公式将在http://opencv.willowgarage.com/documentation/cpp/miscellaneous_image_transformations.html中给出的图像进行转换吗? - Kaushal
1
@kaushalyjain:是的,但正如我所说的:Hue在第一个通道中结束,S在第二个通道中,V在第三个通道中。imshow不解释颜色空间,它假定BGR(至少在pre-2.x cvShowImage中是这样)。你看到的是HSV编码为BGR ;) - zerm
哦!明白了...非常感谢!! 基于这个,我有另一个问题...我将把它作为一个新问题发布...请努力回答那个问题...!! :) - Kaushal

4

如前所述,将图像转换为HSV后立即显示没有意义,但是这里有一个例子说明如何使用V通道:

如果您只想提取V通道,则可以使用cvtColor并使用来自HSV图像的第三个(V)通道来设置该图像灰度副本的强度:

Mat grayImg, hsvImg;
cvtColor(img, grayImg, CV_BGR2GRAY);
cvtColor(img, hsvImg, CV_BGR2HSV);
uchar* grayDataPtr = grayImg.data;
uchar* hsvDataPtr = hsvImg.data;
for (int i = 0; i < img.rows; i++)
{
    for (int j = 0; j < img.cols; j++)
    {
        const int hi = i*img.cols*3 + j*3,
                  gi = i*img.cols + j;
        grayDataPtr[gi] = hsvDataPtr[hi + 2];
    }
}
imshow("V-channel", grayImg);

0
cv::Mat hsv;
std::vector<cv::Mat> channels;
cv::split(hsv, channels);

还有可能

[0] = H
[1] = S
[2] = V

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接