OpenCV-图像处理(20、霍夫变换-直线)
霍夫直线变换介绍
- Hough Line Transform用来做直线检测
- 前提条件 – 边缘检测已经完成
- 平面空间到极坐标空间转换
霍夫线变换的原理
众所周知, 一条直线在图像二维空间可由两个变量表示. 如:
<1>在笛卡尔坐标系: 可由参数: 斜率和截距(m,b)表示。
<2>在极坐标系: 可由参数: 极径和极角(r, θ)表示。
可以用极坐标系来表示直线. 因此, 直线的表达式可为:
化简便可得到:
凡是,通过点(xxx0,yyy0)的直线,都可以表示成
则,这就意味着每一对(rrrθ,θθθ)代表一条通过点(xxx0,yyy0)的直线。如果对于一个给定点(xxx0,yyy0)我们在极坐标对极径极角平面绘出所有通过它的直线, 将得到一条正弦曲线. 例如, 对于给定点xxx0= 8 和yyy0= 6 我们可以绘出下图 (此时,rrrθ和θθθ为变量):
只绘出满足下列条件的点 r>0 和 0< θ < 2π .我们可以对图像中所有的点进行上述操作. 如果两个不同点进行上述操作后得到的曲线在平面 θ-r 相交, 这就意味着它们通过同一条直线. 例如,接上面的例子我们继续对点xxx1= 9 和yyy1= 4和点 xxx2= 12 和yyy2= 3 绘图, 得到下图:
这三条曲线在平面相交于点 (0.925, 9.6), 坐标表示的是参数对 θ-r 或者是说点(xxx0,yyy0), 点(xxx1,yyy1)和点(xxx2,yyy2)组成的平面内的的直线。
以上的说明表明,一般来说, 一条直线能够通过在平面 θ-r 寻找交于一点的曲线数量来检测。而越多曲线交于一点也就意味着这个交点表示的直线由更多的点组成. 一般来说我们可以通过设置直线上点的阈值来定义多少条曲线交于一点我们才认为检测到了一条直线。
这就是霍夫线变换要做的. 它追踪图像中每个点对应曲线间的交点. 如果交于一点的曲线的数量超过了阈值, 那么可以认为这个交点所代表的参数对(θθθ,rrrθ)在原图像中为一条直线。
OpenCV中的霍夫线变换
霍夫线变换是一种用来寻找直线的方法. 在使用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像.
OpenCV支持三种不同的霍夫线变换,它们分别是:
标准霍夫变换(Standard Hough Transform,SHT),
多尺度霍夫变换(Multi-Scale Hough Transform,MSHT),
累计概率霍夫变换(Progressive Probabilistic Hough Transform ,PPHT)。
其中,多尺度霍夫变换(MSHT)为经典霍夫变换(SHT)在多尺度下的一个变种。累计概率霍夫变换(PPHT)算法是标准霍夫变换(SHT)算法的一个改进,它在一定的范围内进行霍夫变换,计算单独线段的方向以及范围,从而减少计算量,缩短计算时间。之所以称PPHT为“概率”的,是因为并不将累加器平面内的所有可能的点累加,而只是累加其中的一部分,该想法是如果峰值如果足够高,只用一小部分时间去寻找它就够了。这样猜想的话,可以实质性地减少计算时间。在OpenCV中,我们可以用HoughLines函数来调用标准霍夫变换SHT和多尺度霍夫变换MSHT。
而HoughLinesP函数用于调用累计概率霍夫变换PPHT。累计概率霍夫变换执行效率很高,所有相比于HoughLines函数,我们更倾向于使用HoughLinesP函数。总结一下,OpenCV中的霍夫线变换有如下三种:
- <1>标准霍夫变换(StandardHough Transform,SHT),由HoughLines函数调用。
- <2>多尺度霍夫变换(Multi-ScaleHough Transform,MSHT),由HoughLines函数调用。
- <3>累计概率霍夫变换(ProgressiveProbabilistic Hough Transform,PPHT),由HoughLinesP函数调用。
相关的API介绍
1. HoughLines( )函数详解
标准的霍夫变换 cv::HoughLines从平面坐标转换到霍夫空间,最终输出是 (θ,rθ)表示极坐标空间
void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 )
说明:
cv::HoughLines(
InputArray src, // 输入图像,必须8-bit的灰度图像
OutputArray lines, // 输出的极坐标来表示直线,经过调用HoughLines函数后储存了霍夫线变换检测到线条的输出矢量。每一条线由具有两个元素的矢量(ρ,θ)表示,其中,ρ是离坐标原点((0,0)(也就是图像的左上角)的距离。 θ是弧度线条旋转角度(0~ 垂直线,π/2~水平线)。
double rho, // 生成极坐标时候的像素扫描步长,一般取值为 1 ,不要大于图像尺寸的一半
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180,即表示一度
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线
double srn=0;// 是否应用多尺度的霍夫变换,如果不是设置0表示经典霍夫变换,多尺度表示的是使用图像金字塔,即多尺度图上进行霍夫变换
double stn=0;//是否应用多尺度的霍夫变换,如果不是设置0表示经典霍夫变换
double min_theta=0; // 表示角度扫描范围 0 ~180之间, 默认即可
double max_theta=CV_PI
) // 一般情况是有经验的开发者使用,需要自己反变换到平面空间
另外,关于霍夫变换的详细解释,可以看此英文页面:
http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm
2. HoughLinesP( )函数详解
- 此函数在HoughLines的基础上末尾加了一个代表Probabilistic(概率)的P,表明它可以采用累计概率霍夫变换(PPHT)来找出二值图像中的直线。
- 霍夫变换直线概率 cv::HoughLinesP最终输出是直线的两个点(xxx0,yyy0,xxx1,yyy1)
void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0 )
说明:
cv::HoughLinesP(
InputArray src, // 输入图像,必须8-bit的灰度图像
OutputArray lines, // 输出的极坐标来表示直线,经过调用HoughLinesP函数后后存储了检测到的线条的输出矢量,每一条线由具有四个元素的矢量(x_1,y_1, x_2, y_2) 表示,其中,(x_1, y_1)和(x_2, y_2) 是是每个检测到的线段的结束点。
double rho, // 生成极坐标时候的像素扫描步长,一般取值为 1
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180,即表示一度
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线
double minLineLength=0;// 最小直线长度,有默认值0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来。
double maxLineGap=0;// 最大间隔,有默认值0,允许将同一行点与点之间连接起来的最大的距离。
)
程序代码:
#include<opencv2/opencv.hpp>
#include<iostream>using namespace std;
using namespace cv;void main(int argc, char** argv)
{//1. 读取图像Mat src, canny, dst;src = imread("E:/Experiment/OpenCV/Pictures/LineTest.jpg");imshow("src", src);//2. 获取边缘Canny(src, canny, 100, 200);imshow("canny", canny);//3. 转成灰度图像cvtColor(canny, dst, CV_GRAY2BGR);//将二值图转换为RGB图颜色空间,这里重新创建一张空Mat也行//4. 霍夫变换检测vector<Vec4f> plines;//保存霍夫变换检测到的直线HoughLinesP(canny, plines, 1, CV_PI / 180, 10, 0, 10);//提取边缘时,会造成有些点不连续,所以maxLineGap设大点//5. 显示检测到的直线Scalar color = Scalar(0, 0, 255);//设置颜色for (size_t i = 0; i < plines.size(); i++){Vec4f hline = plines[i];line(dst, Point(hline[0], hline[1]), Point(hline[2], hline[3]), color, 3, LINE_AA);//绘制直线}imshow("plines", dst);waitKey(0);
}
运行截图
参考博客:
- https://blog.csdn.net/poem_qianmo/article/details/26977557?utm_source=tuicool&utm_medium=referral (强烈读者推荐阅读)
- https://blog.csdn.net/huanghuangjin/article/details/81165826
- https://blog.csdn.net/LYKymy/article/details/83186697
OpenCV-图像处理(20、霍夫变换-直线)相关推荐
- OpenCV图像处理视频教程——入门篇(二)
文章目录 10 膨胀与腐蚀 (1)形态学操作(morphology operators)--膨胀.腐蚀 (2)相关API (3)动态调整结构元素大小TrackBar 11 形态学操作 (1)开操作- ...
- 初识霍夫变换——霍夫变换直线检测原理(Line Detection)
参考博客: 1.Opencv学习笔记-----霍夫变换直线检测及原理理解 2.霍夫变换检测直线原理及实例 3.霍夫变换直线检测(Line Detection)原理及示例 霍夫变换(Hough Tran ...
- 【youcans 的 OpenCV 例程200篇】157. 霍夫变换直线检测
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中 [youcans 的 OpenCV 例程20 ...
- python 检测直线 交点_Python+OpenCV图像处理——实现直线检测
简介: 1.霍夫变换(Hough Transform) 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法.主要用来从图像中分离出具有某种相同特征的几何形状(如,直线 ...
- 霍夫变换检测直线 c语言,opencv之霍夫变换直线检测
霍夫变换检测 霍夫变换之直线检测霍夫变换直线检测 前提条件-边缘检测已经完成 平面空间到极坐标空间的转换(空间域向霍夫域的转换) 检测原理两点确定一条直线,通过一点可以确定无数条直线,极坐标直线公式 ...
- OpenCV图像处理学习十八,霍夫变换实现交通车道线检测
一.霍夫变换 经典霍夫变换用来检测图像中的直线,后来霍夫变换经过扩展可以进行任意形状物体的识别,例如圆和椭圆.霍夫变换运用两个坐标空间之间的变换,将在一个空间中具有相同形状的曲线或直线映射到另一个坐标 ...
- 图像处理之霍夫变换(直线检測算法)
图像处理之霍夫变换(直线检測算法) 霍夫变换是图像变换中的经典手段之中的一个,主要用来从图像中分离出具有某种同样特征的几何 形状(如,直线,圆等).霍夫变换寻找直线与圆的方法相比与其他方法能够更好的降 ...
- 【图像处理基础】基于matlab霍夫变换直线识别(拟合角平分线)【含Matlab源码 2575期】
⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[图像处理基础]基于matlab霍夫变换直线识别(拟合角平分线)[含Matlab源码 2575期] 点击上面蓝色字体,直接付费下载,即可. ...
- OpenCV图像处理(Python)学习笔记
OpenCV图像处理 OpenCV图像处理 第1章 OpenCV入门 第2章 图像处理基础 2.1 基本表示方法 2.2 感兴趣区域(ROI) 第3章 图像运算 3.1 加法运算 3.2 图像加权和 ...
- OpenCV图像处理基础(C++版)
目录 OpenCV环境搭建 加载 修改 保存图像 矩阵的掩膜操作 Mat对象 图像操作 图像混合 调整图像亮度与对比度 绘制形状与文字 模糊图像一 模糊图像二 膨胀与腐蚀 形态学操作 形态学操作应用- ...
最新文章
- 32位系统和64位系统的辨别
- finally 关键字
- Tomcat - Tomcat 网络通信模型剖析 并发参数解读
- premiere cs 下载
- 关于激励函数的一些思考
- 最短路问题之Bellman-ford算法
- BT,eMule,迅雷下载的电影没有字幕的解决方法
- AssertionError: Invalid device id 和RuntimeError: CUDA error: invalid device ordinal
- MYSQL 表锁情况查看
- android第三方代码,Android--第三方控件--okHttp(示例代码)
- c语言横坐标加一怎么表示,C语言 打印一个用字符表示的菱形或正(倒)三角形...
- excel宏计算机,Excel怎么设置宏 Excel宏设置图文教程-电脑教程
- SecureCRT免费安装教程
- 抖音养号上热门技巧(超详细)
- docker compose容器域名配置
- 厉害了,学霸利用贪心算法找偷车贼
- SQL Server 数据库修复专家SQLRescue
- VUE实现长时间未操作退出登录
- x265-1.8版本-common/pixel.cpp注释
- 中国研究的超级系统计算机,打造超级系统U盘
热门文章
- 【Python学习笔记】集合set
- jquery easyui 输入框 禁止输入负数 设置属性data-options=min:0,required:true
- 用Java实现向Cassandra数据库中插入和查询数据
- 兼容sdk7iOS7的issue解决小片段总结
- 戴尔vStart:加快虚拟化,并马上应用戴尔私有云
- QT添加资源文件并使用
- 【SpringBoot_ANNOTATIONS】自动装配 02 @Resource @Inject
- 【Docker】01 Docker概述
- unity3D使用User32.dll
- Android的硬件缩放技术优化执行效率 Screen.SetResolution