Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于OpenCV的HSV颜色检测_Opencv_Detection_Hsv - Fatal编程技术网

基于OpenCV的HSV颜色检测

基于OpenCV的HSV颜色检测,opencv,detection,hsv,Opencv,Detection,Hsv,“红色”颜色检测尚未工作。下面的代码用于检测输入图像中的红色条,并返回在相应位置显示白色条的遮罩图像 InputRGB图像中“红色”条的相应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(inputRGBimag

“红色”颜色检测尚未工作。下面的代码用于检测输入图像中的红色条,并返回在相应位置显示白色条的遮罩图像

InputRGB图像中“红色”条的相应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;
}

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

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

OpenCV中的HSV具有以下范围:
0确保图像使用通道顺序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;
}

祝你好运!:)

两件事:第一个色调被分成两个区域:0到x和x到180,所以你需要两个区域,否则你必须“移动”你的色调。第二:可能会将饱和度和值范围增加到0..255或n..255,但您的测试结果很奇怪。明天将测试您的输入名为
inputgbimage
,但您可以使用标志
cv::COLOR\u BGR2HSV
将其转换为HSV。那么,您使用的通道顺序是RGB还是BGR?如果您使用前者,它将解释为什么会检测到蓝色区域。@nils:谢谢您的提示!我确实忽略了代码中RGB和BGR的细节!用cv::COLOR\u RGB2HSV替换cv::COLOR\u BGR2HSV,一切正常!!顺便说一下,使用SWIFT,图像源于UIImage,因此(在nils的提示下)现在进行以下转换:UIImage->RGBA2RGB->RGB->HSV。。。。OpenCV包装器使用的两种方法是:for(imageArray中的id image){if([image isKindOfClass:[UIImage class]]){cv::matImage=[image CVMat3];matImages.push_back(matImage);}}和-(cv::Mat)CVMat3{cv::Mat result=[self CVMat];cv::cvtColor(结果,结果,CV_RGBA2RGB);返回结果;}
    // or (H > 100) (...closing HSV-circle)
    cv::inRange(imageHSV, cv::Scalar(100, 53, 185, 0), cv::Scalar(180, 255, 255, 0), imgThreshold);
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;
}