【问题标题】:OpenCV color identificationOpenCV颜色识别
【发布时间】:2011-12-18 13:00:02
【问题描述】:

您好,我正在尝试构建简单的颜色识别程序。我已经拍摄了一张图像(黄色和粉红色)并将其转换为 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 指定其他值。

我需要输入什么值?我错过了什么吗?

【问题讨论】:

    标签: python c opencv colors


    【解决方案1】:

    我认为您遇到的问题是由于 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
      

      这就是你的代码对我有用的原因。

      【讨论】:

      • 嗨,我使用的是 OpenCV 2.1.0.3。我使用的是 ubuntu 1104,64 位。在突触中,它显示为最新版本。我认为 64 位的存储库不会像 32 位那样定期更新。我插入了这些行,我得到了值 H: 30, S:255, V:255
      • 我刚刚意识到你的标量中有第四个值。第四个值的行为可能是未定义的,因为它是一个 3 通道图像。您应该将该行更改为cvInRangeS(imgHsv, cvScalar(25, 80, 80), cvScalar(34, 255, 255), imgThreshold);
      • 好的,我只是将阈值的上限范围从 255 增加到 256(35、256、256,256),它起作用了。 cvInRangeS(imgHsv, cvScalar(25, 245, 245,0), cvScalar(35, 256, 256,256), imgThreshold);.我应该注意到 cvInRangeS /* dst(idx) = lower 的 cmets
      • cvInRangeS 的文档自相矛盾。在描述中,它说上限是包容性的,但函数显示它是小于而不是小于或等于。我相信它是包容的。我认为您的更改有效,因为您将第四个值更改为零。但我仍然建议删除第四个值。
      • 我将第四个值保持为非零。 cvInRangeS(imgHsv, cvScalar(25, 245, 245,245), cvScalar(35, 255, 255,255), imgThreshold);。它没有用。超过上限的值可以正常工作cvInRangeS(imgHsv, cvScalar(25, 245, 245,245), cvScalar(35, 256, 256,256), imgThreshold);
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多