OpenCV颜色识别
你好,我正在尝试制作一个简单的颜色识别程序。我拍了一张包含黄色和粉色的图片,并把它转换成HSV颜色空间。然后我使用阈值来识别黄色区域。但我得到的输出是黑色的图像。我想要的是把黄色区域填充成白色,其他地方则是黑色。
IplImage *imgRead= cvLoadImage("yellow.jpeg",CV_LOAD_IMAGE_COLOR);
if(!imgRead) {
fprintf(stderr, "Error in reading image\n");
exit(1);
}
IplImage *imgHsv = cvCreateImage(cvGetSize(imgRead),8, 3);
cvCvtColor(imgRead, imgHsv,CV_BGR2HSV);
IplImage *imgThreshold = cvCreateImage(cvGetSize(imgRead),8, 1);
cvInRangeS(imgHsv, cvScalar(25, 80, 80,80), cvScalar(34, 255, 255,255), imgThreshold);
cvShowImage("image",imgThreshold);
cvWaitKey(0);
在上面的代码中,我计算出黄色的HSV值是30。(在gimp中,黄色的HSV值是60)。在cvInRangeS
中,除了色相值之外,我不太确定如何为cvScalar
指定其他值。
我需要填入什么值?我是不是漏掉了什么?
2 个回答
4
我觉得你遇到的问题是因为HSV数据的范围被缩放到8位。通常,正如你在使用GIMP时注意到的,HSV的范围是这样的:
H -> [0, 360] S -> [0, 100] V -> [0, 100]
但是,OpenCV对这些值的处理方式是这样的:
(H / 2) -> [0, 180] (so that the H values can be stored in 8-bits) S -> [0, 255] V -> [0, 255]
这就是为什么你计算出来的色相值是30而不是60的原因。所以,要过滤掉除了黄色以外的所有颜色,你的cvInRangeS
调用应该像这样:
cvInRangeS(imgHsv, cvScalar(25, 245, 245, 0), cvScalar(35, 255, 255, 255), imgThreshold);
在HSV中,第四个通道是没有用的。这个调用会让你的颜色检测阈值在每个维度上产生10个噪声。
正如SSteve提到的,你的阈值应该是有效的,但你可能需要扩大阈值的范围,以便捕捉到图像中的黄色调。
希望这能帮到你!
2
我运行了你的代码,结果很好。也许你觉得图片里的黄色并没有那么黄。
补充: 另一个可能的不同之处是,我使用的是OpenCV 2.3。你用的是什么版本呢?
好的,再补充一下: 你有没有试着查看一下你的黄色值?这会给你一个明确的答案,告诉你在cvInRangeS中应该使用什么值。在调用cvCvtColor之后,加上这两行代码:
uchar* ptr = (uchar*)(imgHsv->imageData);
printf("H: %d, S:%d, V:%d\n", ptr[0], ptr[1], ptr[2]);
对于我的图片,我得到了:
H: 30, S:109, V:255
这就是为什么我的代码对我有效的原因。