点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
本文转载自:OpenCV学堂

霍夫直线检测

对于图像来说可以从笛卡尔坐标系统转换到霍夫空间,对于一条直线来说

  • 在笛卡尔坐标系统中表示一条直线有两个参数斜率k与截距b

  • 在霍夫空间中表示一条直线也有两个参数到原点的距离d与角度theta

对于给定任意theta值,都有一个r与之对应,对于点x0=8, y0=6,在霍夫空间有如下的曲线:

当有很多点在霍夫空间的曲线相交于一点时候

就说明这些点具有相同的theta与r,即它们都属于同一条直线,而参数theta与r就是该直线在霍夫空间的直线参数方程。

OpenCV中标准霍夫直线检测源码部分:

// stage 1. fill accumulator
for( i = 0; i < height; i++ )for( j = 0; j < width; j++ ){if( image[i * step + j] != 0 )for(int n = 0; n < numangle; n++ ){int r = cvRound( j * tabCos[n] + i * tabSin[n] );r += (numrho - 1) / 2;accum[(n+1) * (numrho+2) + r+1]++;}}// stage 2. find local maximums
findLocalMaximums( numrho, numangle, threshold, accum, _sort_buf );// stage 3. sort the detected lines by accumulator value
std::sort(_sort_buf.begin(), _sort_buf.end(), hough_cmp_gt(accum));// stage 4. store the first min(total,linesMax) lines to the output buffer
linesMax = std::min(linesMax, (int)_sort_buf.size());
double scale = 1./(numrho+2);lines.create(linesMax, 1, type);
Mat _lines = lines.getMat();
for( i = 0; i < linesMax; i++ )
{LinePolar line;int idx = _sort_buf[i];int n = cvFloor(idx*scale) - 1;int r = idx - (n+1)*(numrho+2) - 1;line.rho = (r - (numrho - 1)*0.5f) * rho;line.angle = static_cast<float>(min_theta) + n * theta;if (type == CV_32FC2){_lines.at<Vec2f>(i) = Vec2f(line.rho, line.angle);}else{CV_DbgAssert(type == CV_32FC3);_lines.at<Vec3f>(i) = Vec3f(line.rho, line.angle, (float)accum[idx]);}
}

相关API使用

OpenCV中关于霍夫直线检测有两个API,一个被称为标准霍夫变换直线检测,另外一个叫霍夫直线检测。二者之间的区别在于,前者会直接输出theta与r,还有累加和,后者会直接输出相关线段的平面坐标。

void cv::HoughLines(InputArray image, // 输入参数OutputArray lines, // 输出结果vector<Vec2f>, vector<Vec3f>double rho, // 距离步长d=1, 是指该直线到原点距离,对于屏幕坐标是左上角点double theta, // 角度步长1°int threshold, // 阈值,是指累加数目double srn = 0, // 多尺度检测需要,默认为0double stn = 0, // 多尺度检测需要,默认为0double min_theta = 0, // 直线旋转角度double max_theta = CV_PI // 直线旋转角度
)

对输出的结果是Vec2f的话为(r, theta)如果是Vec3f的话为(r, theta, votes)

当r值大于零的时候表示直线在X轴下方有垂直距离
当r值小于零的时候表示直线在X轴上方有垂直距离

首先对输入图像进行二值化

// 二值化
Mat dst, gray, binary;
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("binary", binary);

标准霍夫直线检测代码如下

// 绘制直线
Point pt1, pt2;
for (size_t i = 0; i < lines.size(); i++)
{float rho = lines[i][0]; // 距离float theta = lines[i][1]; // 角度float votes = lines[i][2]; // 累加printf("rho %.2f, theta : %.2f, votes : %.2f \n", rho, theta, votes);double a = cos(theta), b = sin(theta);double x0 = a*rho, y0 = b*rho;pt1.x = cvRound(x0 + 1000 * (-b));pt1.y = cvRound(y0 + 1000 * (a));pt2.x = cvRound(x0 - 1000 * (-b));pt2.y = cvRound(y0 - 1000 * (a));line(src, pt1, pt2, Scalar(0, 0, 255), 1, LINE_AA);
}
imshow("contours", src);

对上述的代码解释,其中x0与y0是直线上的点,1000是表示对改点延长到直线上距离,上述代码计算公式很多人不理解,特手绘白纸一张如下:

使用霍夫直线变换

假设有如下图像:

通过标准霍夫直线变换实现如下直线分类与最大直线提取

  • 左侧倾斜直线

  • 右侧倾斜直线

  • 水平或者垂直线

  • 长度最大直线

代码实现如下

void hough_lines_demo(Mat &image, Mat &binary) {// 标准霍夫直线检测vector<Vec3f> lines;HoughLines(binary, lines, 1, CV_PI / 180, 100, 0, 0);// 绘制直线Point pt1, pt2;for (size_t i = 0; i < lines.size(); i++){float rho = lines[i][0]; // 距离float theta = lines[i][1]; // 角度float votes = lines[i][2]; // 累加printf("rho %.2f, theta : %.2f, votes : %.2f \n", rho, theta, votes);double a = cos(theta), b = sin(theta);double x0 = a*rho, y0 = b*rho;pt1.x = cvRound(x0 + 1000 * (-b));pt1.y = cvRound(y0 + 1000 * (a));pt2.x = cvRound(x0 - 1000 * (-b));pt2.y = cvRound(y0 - 1000 * (a));int angle = round((theta / CV_PI) * 180);printf("angle : %d\n", angle);if (i == 0) {line(image, pt1, pt2, Scalar(0, 255, 0), 1, LINE_AA);putText(image, "max-line", Point((pt1.x + pt2.x) / 2, (pt1.y + pt2.y) / 2), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255), 2, 8);continue;}if (rho > 0) { // 右倾line(image, pt1, pt2, Scalar(0, 0, 255), 1, LINE_AA);if (angle == 90) { // 水平线line(image, pt1, pt2, Scalar(255, 255, 0), 1, LINE_AA);}if (angle <= 1) { // 垂直线line(image, pt1, pt2, Scalar(0, 255, 255), 1, LINE_AA);}}else { // 左倾line(image, pt1, pt2, Scalar(255, 0, 0), 1, LINE_AA);}}imshow("result", image);
}

运行结果如下:

下载1:OpenCV-Contrib扩展模块中文版教程在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。交流群欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

OpenCV标准霍夫直线检测详解相关推荐

  1. opencv值霍夫直线检测原理

    转载于CheerM的博客园博客 霍夫变换--直线检测 考古debug,其实很久之前就解决的bug--一直忘记过来改文章-.欸 =============================原文====== ...

  2. 【OpenCv】霍夫直线检测

    文章目录 前言 1 原理 2 算法流程 3 优缺点 前言   Hough变换是实现边缘检测的一种有效方法,其基本思想是将测量空间的一点变换到参量空间的一条曲线或曲面,而具有同一参量特征的点变换后在参量 ...

  3. OpenCV基于Python霍夫圆检测—标准霍夫圆检测

    标准霍夫圆检测 1. 简介 2. 标准霍夫圆检测 2.1 情形一 2.2 情形二 2.3 情形三 3. 程序演示 4. 结尾 参考资料 1. 简介 1972年,R. D. Duda和P. E. Har ...

  4. QT+opencv学习笔记(5)——霍夫直线检测、圆检测及椭圆检测

    开发环境为:win10+QT5.8+opencv3.2 Hough变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛.最基本的Hough变换是从黑白图像中检测直线,还可以经过改进检测圆.椭 ...

  5. 基于opencv的c++图像处理(霍夫直线检测与最小二乘法直线拟合)

    前言 基于opencv的c++接口,实现标准的霍夫直线检测.基于统计概率的霍夫直线检测.以及最小二乘法直线拟合. 相关的opencv接口解析 CV_EXPORTS_W void HoughLines( ...

  6. OpenCV霍夫直线检测的实例(附完整代码)

    OpenCV霍夫直线检测的实例 OpenCV霍夫直线检测的实例 OpenCV霍夫直线检测的实例 #include <opencv2/imgproc.hpp> #include <op ...

  7. android openCV检测图像的基本特征,包括Canny边缘检测、Harris角点检测、霍夫直线检测-基于Android studio

    实现平台:windows下的Android studio1.4 依赖库:openCV3.1.0 程序安装平台:Android6.0 实现的功能:从手机中选择一张图片,检测图片的基本特征,通过menu菜 ...

  8. c++版本opencv(36.霍夫直线检测37.直线类型与线段-)

    c++版本opencv(36.霍夫直线检测37.直线类型与线段-) 一.36.霍夫直线检测- 二,37.直线类型与线段- 来自网易云课堂贾志刚老师 一.36.霍夫直线检测- 同一条直线上的点,r和c塔 ...

  9. Android OpenCV(三十二):霍夫直线检测

    霍夫变换利用点与线之间的对偶性,将图像空间中直线上离散的像素点通过参数方程映射为霍夫空间中的曲线,并将霍夫空间中多条曲线的交点作为直线方程的参数映射为图像空间中的直线.给定直线的参数方程,可以利用霍夫 ...

最新文章

  1. java负载均衡框架_SpringCloud与Consul集成实现负载均衡功能
  2. HDU 4857 Couple doubi(找循环节)
  3. 关于SharePoint 2010体系架构的几个话题
  4. 从音乐到全“声”态,腾讯音乐发展的“中国范本”
  5. 【Linux】一步一步学Linux——bzip2命令(65)
  6. 伺服系统 计算机仿真,减摇鳍电伺服系统的计算机仿真研究-应用科技-哈尔滨工程大学.PDF...
  7. 学python要多久-python入门要学多久
  8. Hbase教程(一) Hbase入门教程
  9. JDK异常处理No appropriate protocol
  10. p0f - 被动探测操作系统工具
  11. 【日麻雀魂】何切300问 维持最大牌效
  12. 主流视频通话SDK比较【转】
  13. 科普一下,什么是网站系统的性能,可用性,可伸缩性,可扩展性?
  14. 科学计算机sd mode使用方法,你是否知道科学计算器的使用方法
  15. ASP.NET动态网站开发培训-23.论文管理系统(三、制作论文内容页面)
  16. 进入qq空间显示服务器错误,解决QQ空间打开无响应或报错的方法
  17. 搜索引擎排名威新hfqjwl_手机下拉框微莘hfddjwl,手机下拉框微信hfqjdwl作词
  18. Oracle In-Database Archiving演示
  19. rk3568 添加gc2053摄像头驱动
  20. Cisco 9800 WLC PID

热门文章

  1. “AI明星”地平线B轮融资6亿美元!
  2. 十大经典排序算法动画与解析,看我就够了
  3. 百度燎原计划2018强势回归 开放深度学习工程师评价标准
  4. 两次杀人,自动驾驶技术之恶
  5. KonaJDK 助力微服务国密算法使用特性一览
  6. 经典分类:线性判别分析模型!
  7. Datawhale浙大分享(附投票结果)
  8. 【廖雪峰python入门笔记】list_替换元素
  9. CVPR 2022 接收结果出炉!录用 2067 篇,接收数量上升24%(附最新论文速递)
  10. 拿transformer做E2E全景分割,这个通用框架霸榜挑战赛,南大、港大联合提出