我正在一个小的OpenCV项目中,通过从手机相机中检测某种颜色的线条。

总之想:

  • 将输入图像转换为某种颜色的图像(例如,特定上下限范围内的红色)
  • 对所生成的图像应用霍夫线变换,以便仅检测该特定颜色的线
  • 将检测到的线条叠加在原始图像上

  • 这些是我想使用的功能,但我不能安静地确定如何填充丢失的位。


    - (void)processImage:(Mat&)image;
    {
    cv::Mat orig_image = image.clone();
    
    cv::Mat red_image = ??
    
    // Apply houghes transformation to detect lines between a minimum length and a maximum length (I was thinking of using the CV_HOUGH_PROBABILISTIC method..)
    // Comment.. see below..
    


    vector<Vec2f> lines;
    


    HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 );
    


    for( size_t i = 0; i < lines.size(); i++ )
    {
    


    }
    



    任何帮助将不胜感激。

    最佳答案

    您可以使用HSV色彩空间提取色调信息。

    如果有任何问题,这里是一些带有注释的代码:

    int main(int argc, char* argv[])
    {
        cv::Mat input = cv::imread("C:/StackOverflow/Input/coloredLines.png");
    
        // convert to HSV color space
        cv::Mat hsvImage;
        cv::cvtColor(input, hsvImage, CV_BGR2HSV);
    
        // split the channels
        std::vector<cv::Mat> hsvChannels;
        cv::split(hsvImage, hsvChannels);
    
        // hue channels tells you the color tone, if saturation and value aren't too low.
    
        // red color is a special case, because the hue space is circular and red is exactly at the beginning/end of the circle.
        // in literature, hue space goes from 0 to 360 degrees, but OpenCV rescales the range to 0 up to 180, because 360 does not fit in a single byte. Alternatively there is another mode where 0..360 is rescaled to 0..255 but this isn't as common.
        int hueValue = 0; // red color
        int hueRange = 15; // how much difference from the desired color we want to include to the result If you increase this value, for example a red color would detect some orange values, too.
    
        int minSaturation = 50; // I'm not sure which value is good here...
        int minValue = 50; // not sure whether 50 is a good min value here...
    
        cv::Mat hueImage = hsvChannels[0]; // [hue, saturation, value]
    
        // is the color within the lower hue range?
        cv::Mat hueMask;
        cv::inRange(hueImage, hueValue - hueRange, hueValue + hueRange, hueMask);
    
        // if the desired color is near the border of the hue space, check the other side too:
        // TODO: this won't work if "hueValue + hueRange > 180" - maybe use two different if-cases instead... with int lowerHueValue = hueValue - 180
        if (hueValue - hueRange < 0 || hueValue + hueRange > 180)
        {
            cv::Mat hueMaskUpper;
            int upperHueValue = hueValue + 180; // in reality this would be + 360 instead
            cv::inRange(hueImage, upperHueValue - hueRange, upperHueValue + hueRange, hueMaskUpper);
    
            // add this mask to the other one
            hueMask = hueMask | hueMaskUpper;
        }
    
        // now we have to filter out all the pixels where saturation and value do not fit the limits:
        cv::Mat saturationMask = hsvChannels[1] > minSaturation;
        cv::Mat valueMask = hsvChannels[2] > minValue;
    
        hueMask = (hueMask & saturationMask) & valueMask;
    
        cv::imshow("desired color", hueMask);
    
        // now perform the line detection
        std::vector<cv::Vec4i> lines;
        cv::HoughLinesP(hueMask, lines, 1, CV_PI / 360, 50, 50, 10);
    
        // draw the result as big green lines:
        for (unsigned int i = 0; i < lines.size(); ++i)
        {
            cv::line(input, cv::Point(lines[i][0], lines[i][1]), cv::Point(lines[i][2], lines[i][3]), cv::Scalar(0, 255, 0), 5);
        }
    
    
        cv::imwrite("C:/StackOverflow/Output/coloredLines_mask.png", hueMask);
        cv::imwrite("C:/StackOverflow/Output/coloredLines_detection.png", input);
    
        cv::imshow("input", input);
        cv::waitKey(0);
        return 0;
    }
    

    使用此输入图像:

    c&#43;&#43; - OpenCV:如何检测特定颜色的线条?-LMLPHP

    将提取此“红色”颜色(调整hueValuehueRange以检测不同的颜色):

    c&#43;&#43; - OpenCV:如何检测特定颜色的线条?-LMLPHP

    和HoughLinesP从 mask 中检测到这些行(应类似地与HoughLines一起使用):

    c&#43;&#43; - OpenCV:如何检测特定颜色的线条?-LMLPHP

    这也是另一组带有非线的图像...

    c&#43;&#43; - OpenCV:如何检测特定颜色的线条?-LMLPHP

    c&#43;&#43; - OpenCV:如何检测特定颜色的线条?-LMLPHP

    c&#43;&#43; - OpenCV:如何检测特定颜色的线条?-LMLPHP

    关于您的不同问题:
  • 有两个函数HoughLines和HoughLinesP。 HoughLines不会提取线长,但是您可以在后期处理中通过再次检查边缘蒙版的哪些像素(HoughLines输入)对应于提取的线来计算它。
  • 参数:

    图片-边缘图片(应该清楚吗?)
    lines-由 Angular 和位置给出的线,无长度或sth。他们被解释成无限长
    rho-累加器分辨率。线条较大时,它应该越大,越健壮,但是提取出的线条的位置/ Angular 准确性越差
    阈值-越大,误报越少,但是您可能会漏掉一些行
    theta- Angular 分辨率:可以检测到的线越小(取决于方向)越多。如果线条的方向不适合 Angular 步长,则可能无法检测到线条。例如,如果您的CV_PI/180将以分辨率进行检测,则如果您的行的方向为0.5°(例如33.5°),则可能会错过它。

  • 我不太确定所有参数,也许您需要阅读有关霍夫线检测的文献,或者其他人可以在此处添加一些提示。

    如果改用cv::HoughLinesP,则会检测到具有起点和终点的线段,这更易于解释,您可以根据cv::norm(cv::Point(lines[i][0], lines[i][1]) - cv::Point(lines[i][2], lines[i][3]))计算线长

    关于c++ - OpenCV:如何检测特定颜色的线条?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35866411/

    10-10 00:44
    查看更多