博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
霍夫线变换
阅读量:6149 次
发布时间:2019-06-21

本文共 2478 字,大约阅读时间需要 8 分钟。

这一节课将学到使用OpenCV的以下函数 和 来检测图像中的直线.和霍夫线变换的相关知识。


 什么是霍夫线变换?

  1.霍夫线变换是一种检测直线的算法。

  2.在进行霍夫线变换之前必须对图像进行边缘检测处理,所以霍夫线变换的直接输入必须是边缘二值图像。


 如何实现?

  1. 众所周知,一条直线在图像二维空间可由两个变量表示。例如:

      a.在笛卡尔坐标系:可由参数斜率和截距表示。

      b.在即坐标系:可由极径和极角表示。

  2.对于霍夫变换,我们将用极坐标系来表示直线,因此,直线的表达式可以是:

      y = \left ( -\dfrac{\cos \theta}{\sin \theta} \right ) x + \left ( \dfrac{r}{\sin \theta} \right )

      化简得: r = x \cos \theta + y \sin \theta

      一般来说对于点(x0,y0),我们可以将通过这个点得一族直线统一定义为:r_{\theta} = x_{0} \cdot \cos \theta  + y_{0} \cdot \sin \theta

     这就意味着对于每一对(rθ,θ)代表一条通过(x0,y0)的直线。

  3.如果对于一个给定点(x0,y0)我们在极坐标对极径角平面绘出所有通过它的直线,将得到一条正弦曲线。例如,对于给定点x0=θ and y0=6 我们可以绘出下图(在平面)。

       只绘制出满足下列条件的点r>0 and 0<θ<2∏

  4.我们可以对图像中所有的点进行上述操作,如果两个不同点进行上述操作后得到的曲线在平面 θ-r 相交,则表示他们通过同一条直线。

     

        三条曲线相交于(0.925,9.6),坐标表示的是参数对(θ,r),或者说是(x0,y0)和点(x1,y1)和点(x2,y2)。组成的平面内的直线。

  5.说了这么都到底是想表达些什么呢?首先二值图像上面的点我们可以根据其取值不同来进行不同的分类,然后将这些点转化为极坐标点,极坐标点在极径极角平面可以画出所有通过他的直线,  我们将得到一条正弦曲线,我们可以根据这一特性来确定

在二值图像上那些亮度相近的点是一条直线上的。

  6.这就是霍夫变换所做的。他追踪图像中每个点对应曲线间的交点,如果交与一点的曲线数量超过了某个阈值,那么就可以认为这个交点是图像中的一条直线。


OpenCV实现了两种霍夫变换:

  a.标准霍夫变换

    原理在上面的部分已经讲的差不多了,他能给我们提供一组参数对(θ,rθ)的集合来表示检测到的对象。早OpenCv中该变化使用HoughLines来实现

  b.统计概率霍夫线变换

    这是执行起来效率更高的霍夫线变换,他输出检测到的直线的端点(x0,y0,x1,y1)。在OpenCV中他通过函数HoughLinesP来实现。


代码

#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include 
using namespace cv;using namespace std;int main(int argc, char** argv){ const char* filename = "pic1.jpg"; Mat src = imread("res.jpg"); if(src.empty()) { cout << "can not open " << filename << endl; return -1; } Mat dst, cdst; Canny(src, dst, 50, 200, 3); cvtColor(dst, cdst, CV_GRAY2BGR); #if 0 vector
lines; HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 ); for( size_t i = 0; i < lines.size(); i++ ) { float rho = lines[i][0], theta = lines[i][1]; Point pt1, pt2; 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( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA); } #else vector
lines; HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 ); for( size_t i = 0; i < lines.size(); i++ ) { Vec4i l = lines[i]; line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA); } #endif imshow("source", src); imshow("detected lines", cdst); waitKey(); return 0;}

 

 

  

  

  

转载于:https://www.cnblogs.com/A-FM/p/6118648.html

你可能感兴趣的文章
DropDownList 控制日期控件显示格式
查看>>
RecycleView设置顶部分割线(记录一个坑)
查看>>
【设计模式系列】单例模式的7种写法
查看>>
汉字转拼音 (转)
查看>>
Machine Learning Techniques -6-Support Vector Regression
查看>>
会计基础_001
查看>>
ajax请求拿到多条数据拼接显示在页面中
查看>>
小程序: 查看正在写的页面
查看>>
Jenkins持续集成环境部署
查看>>
检查磁盘利用率并且定期发送告警邮件
查看>>
MWeb 1.4 新功能介绍二:静态博客功能增强
查看>>
摄像机与绕任意轴旋转
查看>>
rsync 服务器配置过程
查看>>
预处理、const与sizeof相关面试题
查看>>
爬虫豆瓣top250项目-开发文档
查看>>
Elasticsearch增删改查
查看>>
oracle归档日志增长过快处理方法
查看>>
有趣的数学书籍
查看>>
teamviewer 卸载干净
查看>>
多线程设计模式
查看>>