使用OpenCV进行HSV颜色检测

时间:2015-03-29 16:24:53

标签: opencv detection hsv

“红色”颜色检测尚未开始。以下代码应该检测输入图像中的红色条,并返回一个在相应位置显示白条的蒙版图像。

inputRGBimage中“红色”条的相应HSV值为:H = 177,S = 252,V = 244

    cv::Mat findColor(cv::Mat inputRGBimage) {

    cv::Mat imageHSV(inputRGBimage.rows, inputRGBimage.cols, CV_8UC3);
    cv::Mat imgThreshold(inputRGBimage.rows, inputRGBimage.cols, CV_8UC1);

    // convert input-image to HSV-image
    cvtColor(inputRGBimage, imageHSV, cv::COLOR_BGR2HSV);

    // for red: (H < 14)
    // cv::inRange(imageHSV, cv::Scalar(0, 53, 185, 0), cv::Scalar(14, 255, 255, 0), imgThreshold);
    // or (H > 165) (...closing HSV-circle)
    cv::inRange(imageHSV, cv::Scalar(165, 53, 185, 0), cv::Scalar(180, 255, 255, 0), imgThreshold);

    return imgThreshold;
}

下面的两张图显示了inputRGBimage(顶部)和返回的imgThreshold(底部)。正如您所看到的,面具未显示预期颜色为“红色”的白色条,但在“蓝色”条上显示了一些未知原因。为什么????

wrong mask 01

cv :: inRange代码行(即H> 120)的以下更改再次说明颜色检测实际上没有按预期运行:

    // or (H > 120) (...closing HSV-circle)
    cv::inRange(imageHSV, cv::Scalar(120, 53, 185, 0), cv::Scalar(180, 255, 255, 0), imgThreshold);

wrong mask 02

作为第三个例子:(H> 100):

    // or (H > 100) (...closing HSV-circle)
    cv::inRange(imageHSV, cv::Scalar(100, 53, 185, 0), cv::Scalar(180, 255, 255, 0), imgThreshold);

wrong mask 03

为什么我的3个代码示例中的颜色意外顺序(将H值从165降低到100)显示掩码顺序为“blue-&gt; violet-&gt; red-&gt; orange”而不是实际预期HSV车轮粗略顺序为“红色 - >紫色 - >蓝色 - >绿色 - >黄色 - >橙色”?????

HSV table

OpenCV中的HSV范围: 0 <= H <= 180, 0&lt; = S&lt; = 255, 0 <= V <= 255,(不完全像上面的图示 - 但是OpenCV HSV颜色的颜色顺序应该相同 - 或者不是???)

1 个答案:

答案 0 :(得分:2)

确保图像使用通道顺序B,G,R。此外,对于红色,您需要检查两个值范围,一个围绕H=0,另一个围绕H=180。你可以尝试这个功能:

cv::Mat findColor(const cv::Mat & inputBGRimage, int rng=15)
{
    // Make sure that your input image uses the channel order B, G, R (check not implemented).
    cv::Mat input = inputBGRimage.clone();
    cv::Mat imageHSV;//(input.rows, input.cols, CV_8UC3);
    cv::Mat imgThreshold, imgThreshold0, imgThreshold1;//(input.rows, input.cols, CV_8UC1);
    assert( ! input.empty() );

    // convert input-image to HSV-image
    cv::cvtColor( input, imageHSV, cv::COLOR_BGR2HSV );

    // In the HSV-color space the color 'red' is located around the H-value 0 and also around the
    // H-value 180. That is why you need to threshold your image twice and the combine the results.
    cv::inRange(imageHSV, cv::Scalar(      0, 53, 185, 0), cv::Scalar(rng, 255, 255, 0), imgThreshold0);

    if ( rng > 0 )
    {
        cv::inRange(imageHSV, cv::Scalar(180-rng, 53, 185, 0), cv::Scalar(180, 255, 255, 0), imgThreshold1);
        cv::bitwise_or( imgThreshold0, imgThreshold1, imgThreshold );
    }
    else
    {
        imgThreshold = imgThreshold0;
    }

    return imgThreshold;
}
祝你好运! :)