在OpenCV中将BGR转换为HSV,C++

6
我试图让网络摄像头拍摄某人面部的BGR照片,将其转换为HSV,并分析这些HSV值,以后将在皮肤检测算法中使用。不幸的是,即使我尝试使用cvtColor()进行转换,该图片似乎仍然以BGR格式进行分析。
我使用下面的代码来测试是否使用了正确的颜色空间。请注意我尝试将饱和度和值设置为0的部分:
Mat faceROI = findFace(first); //basic Mat, region of interest for face (code not included)

Mat temp;
faceROI.convertTo(temp, CV_8UC3); //making sure this has right no. of channels and such

CvScalar s;

IplImage face_ipl = temp; //new header
IplImage* aNew = cvCreateImage(cvGetSize(&face_ipl), face_ipl.depth, 3);

cvCvtColor(&face_ipl, aNew, CV_BGR2HSV);

for(int x = 0; x < faceROI.cols; x++){
    for (int y = 0; y < faceROI.rows; y++){
        s = cvGet2D(aNew, x, y);

        //vvvvvvvvvvv
        s.val[1] = 0; //should be saturation
        s.val[2] = 0; //should be value
        //^^^^^^^^^^^

        cvSet2D(aNew, x, y, s);
    }
}

Mat again(aNew); //<--- is this where something is set back to BGR?
imshow("white", again);

cvReleaseImage(&aNew);

这将生成一张完全蓝色的人脸图片,因此似乎我正在编辑BGR图像的G和R通道,而不是HSV图像的S和V通道。 (我会发布图片,但这是我的第一篇文章,所以我还没有足够的声望。)有人知道这是为什么吗?非常感谢任何想法。

那么你在哪里将图像从HSV转换回BGR? - sgarizvi
这是我的问题的核心...我不认为我会转换回BGR,但结果似乎表明正在发生这种情况。 - Connor
无论图像使用什么颜色空间,imshow函数总是将其解释为简单的RGB或BGR图像。由于您正在将0分配给S和V通道,因此只剩下H通道,它对应于BGR图像中的B。因此,对于imshow函数,again是一个仅在蓝色通道中具有值的BGR图像。这就是为什么您看到蓝色输出的原因。 - sgarizvi
解决方法------>在imshow之前添加cvtColor(again,again,CV_HSV2BGR) - sgarizvi
你的解决方案建议真的很有帮助 - 它给了我预期的结果。(我将值参数更改为255,保持饱和度为0;我的代码结合你的建议产生了一个纯白色的窗口,这是有意义的。)感谢你的帮助! - Connor
1个回答

14

您将C++ Mat样式与旧的C IplImage*混淆在一起,这使得很难看出到底发生了什么。以下是将inputImage转换为HSV的代码:

Mat fullImageHSV;
cvtColor(inputImage, fullImageHSV, CV_BGR2HSV);

请注意,OpenCV中的HSV值为H从0-180,而S和V为0-255,而其他程序往往使用不同的值。还要注意,OpenCV无法正常显示HSV图像,因为它们被解释为RGB而导致颜色失真。


知道了。我觉得 iplImage* 看起来不太友好...还感谢你提供的有关 OpenCV 不能正常显示 HSV 图像的提示,这似乎是我问题的重点所在。非常感谢您的回复。 - Connor
是的,选择一个并坚持使用C或C++ API是个好主意。两者都有自己独特的风格。 - Boyko Perfanov
+100 是指范围和颜色解释的说明。我曾经为此苦恼过! - inblueswithu
请注意,OpenCV无法正常显示HSV图像,这会扭曲颜色,因为它们被解释为RGB。这是一个重要的提示,OpenCV初学者需要注意。 - kdbanman

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