【问题标题】:Highlight lines found by hough transform - OPENCV霍夫变换找到的高亮线 - OPENCV
【发布时间】:2014-06-28 10:48:18
【问题描述】:

在Matlab中,通过将hough变换、houghpeaks和houghlines结合起来,可以在原始图像中显示检测到的线条。

这可以在下图中显示(通过使用 Matlab 的 houghlines 帮助中的示例代码生成)。检测到绿线。蓝色的是最长的:

我在我生成的一个简单合成图像(几个正方形等)上运行了 cv::HoughLines。图片附在此处:

相关代码部分为:

cv::vector<cv::Vec2f> lines;
cv::HoughLines(I_BW, lines, 1, CV_PI/180,200);
cv::Mat linesMat ( lines, true );

查看linesMat矩阵(我将其转换为这种形式,以便我可以使用图像观察来查看数据)同时运行for循环以在边缘图像上添加一条红线我看到rho和theta按长度排序图像中最长的线。

我的输出是:

线条是图像的整个宽度(或高度)。我怎样才能像 Matlab 示例中那样显示实际的线条? 我可以从 rho+theta 回到 x 和 y,但是我必须以某种方式将它们链接到检测到的边缘等 - 也许有一种我缺少的简单方法可以做到这一点?

谢谢!

【问题讨论】:

    标签: matlab opencv hough-transform


    【解决方案1】:

    taoufik 是正确的,我赞成他的回答。 在阅读他的评论之前,我实际上在 OpenCV 2 Computer Vision Application Programming Cookbook 中找到了答案。

    我选择我的答案作为答案,因为它更完整以供将来参考。

    @taoufik - 再次感谢,伙计!

    我将发布一个可能对其他人有用的代码 sn-p(基于我在食谱中找到的解决方案。我只是编写了简短版本,而不是食谱中的优雅类实现)。

    我还在这里添加了一个我写的小函数,它计算 CDF,用于在 Canny 的 Matlab 实现中找到 Canny 边缘检测器的高阈值和低阈值,这给出了很好的结果。通常我也会在边缘检测之前进行高斯模糊(如 Matlab 中的 canny.m 中所示),但附加的图像是综合完美的(无噪声),因此这里是多余的。 我选择了较高的最小投票值(“阈值”),因此只会找到 4 条长线。

    我们将从 main 函数中的代码开始:

    cv::Mat image = cv::imread("shapes.jpg");
    int bins = 256;
    cv::Mat cdf = getGrayCDF(image,bins);
    cv::Mat diffy = cdf>0.7;
    cv::Mat NonZero_Locations;   // output, locations of non-zero pixels 
    cv::findNonZero(diffy, NonZero_Locations);
    double highThreshold = double((NonZero_Locations.at<cv::Point>(0).y))/bins;
    double lowThreshold = 0.4*highThreshold;
    cv::Mat contours;
    // cv::GaussianBlur( image, contours, cv::Size(7,7),2 ); // NOT REQUIRED HERE. Syhnthetic image
    cv::Canny( image, contours, lowThreshold*bins, highThreshold*bins);
    std::vector<cv::Vec4i> lines;
    double rho = 1; // delta_rho resolution
    double theta = CV_PI/180; // delta_theta resolution
    int threshold = 300; // threshold number of votes , I SET A HIGH VALUE TO FIND ONLY THE LONG LINES
    double minLineLength = 0; // min length for a line
    double maxLineGap = 2; // max allowed gap along the line
    cv::HoughLinesP(contours,lines, rho, theta, threshold, minLineLength, maxLineGap); // running probabilistic hough line
    if (image.channels()!=3) {cv::cvtColor(image,image,CV_GRAY2BGR);} // so we can see the red lines
    int line_thickness = 2;
    cv::Scalar color=cv::Scalar(0,0,255);
    std::vector<cv::Vec4i>::const_iterator iterator_lines = lines.begin();
    while (iterator_lines!=lines.end()) {
        cv::Point pt1((*iterator_lines)[0],(*iterator_lines)[1]);
        cv::Point pt2((*iterator_lines)[2],(*iterator_lines)[3]);
        cv::line( image, pt1, pt2, color, line_thickness);
        ++iterator_lines;
    }
    cv::imshow("found lines", image); cvWaitKey(0); cv::destroyWindow("found lines");
    

    我将以计算简单灰度累积分布函数的函数结束:

    cv::Mat getGrayCDF(cv::Mat Input, int histSize){
    cv::Mat InputGray = Input.clone();
    if (InputGray.channels()!=1) {cv::cvtColor(Input,InputGray,CV_BGR2GRAY);}
    float range[] = { 0, histSize  } ;
    const float* histRange = { range };
    bool uniform = true; bool accumulate = false;
    cv::Mat hist;
    calcHist( &InputGray, 1, 0, cv::Mat(), hist, 1, &histSize , &histRange, uniform, accumulate );
    for (int i = 1; i < hist.rows; i++) {
        float* data = hist.ptr<float>(0);
        data[i] += data[i-1];
    }
    return hist/(InputGray.total()); // WE NOW HAVE A *NORMALIZED* COMPUTED CDF!
    }
    

    我对上面给出的 sn-p 的解决方案是:

    希望你觉得这很有用!

    【讨论】:

      【解决方案2】:

      您正在寻找的是概率霍夫变换。在 OpenCV 中,它位于 HoughLinesP() 下。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多