IT评测·应用市场-qidao123.com技术社区

标题: 24.OpenCV中的霍夫直线检测 [打印本页]

作者: 伤心客    时间: 2025-4-15 22:48
标题: 24.OpenCV中的霍夫直线检测
OpenCV中的霍夫直线检测

霍夫直线检测是一种基于参数变换的全局特性提取方法,它能在边沿图像中有效检测出直线,具有鲁棒性强和对噪声干扰容忍度高的特点。本文将从原理、算法实现和 OpenCV 应用三个角度对霍夫直线检测进行详细的阐述,并给出相应的 C++ 代码示例。
1. 霍夫直线检测原理

1.1 根本思想

霍夫直线检测的焦点思想是将图像空间中的每个边沿点转换到一个参数空间中,在这个参数空间中,每一条直线都可以用一组参数来唯一确定。常用的直线参数化方法采用极坐标表现,使得直线方程可以写成:
                                         ρ                            =                            x                            c                            o                            s                            θ                            +                            y                            s                            i                            n                            θ                                  ρ=xcos\theta+ysin\theta                     ρ=xcosθ+ysinθ
其中:

参考图

每个图像中的边沿点(x,y)根据上述方程,会在(ρ,θ)参数空间中对应一条曲线。若图像中存在直线,那么这条直线上的所有点在参数空间中都“交汇”于一个特定的(ρ,θ)点。
1.2 参数空间与累加器

OpenCV为了统计不同边沿点对直线候选参数的支持度,算法构造了一个 累加器

当累加器中某一单位格的票数大于预设的阈值时,便可以认为该参数组合 (ρ,θ)(ρ,θ) 对应的直线在图像中存在。
1.3 标准与概率霍夫变换

OpenCV 提供两种常用的直线检测方法:

2. 算法使用步骤

下面扼要总结霍夫直线检测的主要步骤:
3. OpenCV C++ 实战示例

下面给出一个使用标准霍夫直线变换(HoughLines)的 C++ 示例代码。代码通过 Canny 边沿检测获得二值图像,并对霍夫直线进行参数求解,末了在原图上绘制检测到的直线。
3.1:HoughLines参考代码

  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. using namespace cv;
  4. using namespace std;
  5. int main()
  6. {
  7.     // 读取输入图像
  8.     Mat src = imread("E:/image/ela_modified.jpg");
  9.     if (src.empty())
  10.     {
  11.         cout << "无法加载图像!" << endl;
  12.         return -1;
  13.     }
  14.     // 转换为灰度图并进行边缘检测
  15.     Mat gray, edges;
  16.     cvtColor(src, gray, COLOR_BGR2GRAY);
  17.     Canny(gray, edges, 50, 150, 3);
  18.     // 使用标准霍夫直线变换进行直线检测
  19.     vector<Vec2f> lines; // 每行元素为 (rho, theta)
  20.     HoughLines(edges, lines, 1, CV_PI / 180, 150); // 阈值150可根据图像情况调整
  21.     // 拷贝原图用于显示检测结果
  22.     Mat result = src.clone();
  23.     // 绘制检测到的直线
  24.     for (size_t i = 0; i < lines.size(); i++)
  25.     {
  26.         float rho = lines[i][0], theta = lines[i][1];
  27.         // 利用极坐标公式得到直线上的两个点,便于绘制延长直线
  28.         double a = cos(theta), b = sin(theta);
  29.         double x0 = a * rho, y0 = b * rho;
  30.         Point pt1(cvRound(x0 + 1000 * (-b)),
  31.             cvRound(y0 + 1000 * (a)));
  32.         Point pt2(cvRound(x0 - 1000 * (-b)),
  33.             cvRound(y0 - 1000 * (a)));
  34.         line(result, pt1, pt2, Scalar(0, 0, 255), 2);
  35.     }
  36.     imshow("原图Cany", edges);
  37.     imshow("霍夫直线检测", result);
  38.     waitKey(0);
  39.     return 0;
  40. }
复制代码
直线绘制:使用直线参数 ρθ 计算延长直线上任意两个远距离的点,这样能够包管直线能凌驾整个图像进行显示。

3.2 HoughLinesP参考代码

  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. using namespace cv;
  4. using namespace std;
  5. int main()
  6. {
  7.     // 读取输入图像
  8.     Mat src = imread("E:/image/ela_modified.jpg");
  9.     if (src.empty())
  10.     {
  11.         cout << "无法加载图像!" << endl;
  12.         return -1;
  13.     }
  14.     // 转换为灰度图并进行边缘检测
  15.     Mat gray, edges;
  16.     cvtColor(src, gray, COLOR_BGR2GRAY);
  17.     Canny(gray, edges, 50, 150, 3);
  18.     // 使用标准霍夫直线变换进行直线检测
  19.     vector<Vec4i> linesP;
  20.     HoughLinesP(edges, linesP, 1, CV_PI / 180, 150, 50, 30);
  21.     // 拷贝原图用于显示检测结果
  22.     Mat result = src.clone();
  23.     // 绘制检测到的直线
  24.     for (size_t i = 0; i < linesP.size(); i++) {
  25.         Vec4i l = linesP[i];
  26.         line(result, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 255, 0), 2);
  27.     }
  28.     imshow("原图Cany", edges);
  29.     imshow("霍夫直线检测", result);
  30.     waitKey(0);
  31.     return 0;
  32. }
复制代码

4.总结

霍夫直线检测通过将图像中的边沿点映射到参数空间,并在累加器中统计支持度,从而实现对直线的检测。

借助 OpenCV,我们可以快速实现这一算法,对直线检测、门路识别、车道线提取等实际应用都有着广泛的应用前景。
在实际应用中,霍夫直线检测大概会受到以下因素的影响:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4