OpenCV中的霍夫线变换和霍夫圆变换
一、霍夫线变换
霍夫线变换是OpenCv中一种寻找直线的方法,输入图像为边缘二值图。
原理:
一条直线在图像二维空间可由两个变量表示, 例如:
1、在 笛卡尔坐标系: 可由参数: (m,b) 斜率和截距表示。
2、在 极坐标系: 可由参数: 极径和极角表示。
对于霍夫变换,我们将用 极坐标系 来表示直线。 因此,直线的表达式可为:
化简后得:
一般来说对于点 , 我们可以将通过这个点的一族直线统一定义为:
这就意味着每一对 代表一条通过点
的直线。
如果对于一个给定点 我们在极坐标对极径极角平面绘出所有通过它的直线,将得到一条正弦曲线。例如,对于给定点
and
我们可以绘出下图 (在平面 \theta - r):
只绘出满足下列条件的点 and
。
我们可以对图像中所有的点进行上述操作. 如果两个不同点进行上述操作后得到的曲线在平面 - r 相交, 这就意味着它们通过同一条直线. 例如, 接上面的例子我们继续对点:
,
和点
,
绘图,得到下图:
这三条曲线在 - r 平面相交于点 (0.925, 9.6), 坐标表示的是参数对 (
, r) 或者是说点
, 点
和点
组成的平面内的的直线。
那么以上的材料要说明什么呢? 这意味着一般来说, 一条直线能够通过在平面 - r 寻找交于一点的曲线数量来 检测. 越多曲线交于一点也就意味着这个交点表示的直线由更多的点组成. 一般来说我们可以通过设置直线上点的 阈值 来定义多少条曲线交于一点我们才认为 检测 到了一条直线.
这就是霍夫线变换要做的. 它追踪图像中每个点对应曲线间的交点. 如果交于一点的曲线的数量超过了 阈值, 那么可以认为这个交点所代表的参数对 在原图像中为一条直线。
在OpenCV中霍夫线变换分为两种:
1、标准霍夫线变换
原理在上面的部分已经说明了. 它能给我们提供一组参数对 的集合来表示检测到的直线
在OpenCV 中通过函数 HoughLines 来实现
2、统计概率霍夫线变换
这是执行起来效率更高的霍夫线变换. 它输出检测到的直线的端点
在OpenCV 中它通过函数 HoughLinesP 来实现
实现:
1、标准霍夫线变换
函数为:
void HoughLines( InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double srn = 0, double stn = 0,
double min_theta = 0, double max_theta = CV_PI );
第一个参数为输入图像,应该为灰度图,
第二个参数为输出的检测到的直线的容器
第三个参数为以参数极径单位的分辨率
第四个是以弧度为单位的分辨率
第五个为一条直线所需最少的的曲线交点
int main()
{
RNG rng(12345);
Mat a = imread("1RT05508-0.jpg");
imshow("原图", a);
cvtColor(a, a, CV_RGB2GRAY); //转为灰度图
Canny(a, a, 100, 300, 3); //进行边缘检测
Mat bbb;
cvtColor(a, bbb, CV_GRAY2BGR);
vector<Vec2f> lines;
HoughLines(a, lines, 1, CV_PI / 180, 100); //检测
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(bbb, pt1, pt2, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3, CV_AA); //实现随机颜色
}
imshow("效果图", bbb);
cvWaitKey(10000);
}
效果图:
各参数的作用和标准霍夫变换相同
2、统计概率霍夫线变换
函数为:
void HoughLinesP( InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double minLineLength = 0, double maxLineGap = 0 );
int main()
{
RNG rng(12345);
Mat a = imread("1RT05508-0.jpg");
imshow("原图", a);
cvtColor(a, a, CV_RGB2GRAY); //转为灰度图
Canny(a, a, 100, 300, 3); //边缘检测
Mat bbb;
cvtColor(a, bbb, CV_GRAY2BGR);
vector<Vec4i> lines;
HoughLinesP(a, lines, 1, CV_PI / 180, 50, 50, 10); //检测
for (size_t i = 0; i < lines.size(); i++) //划线
{
Vec4i l = lines[i];
line(bbb, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3, CV_AA); //用的是随机颜色
}
imshow("效果图", bbb);
cvWaitKey(10000);
}
效果图:
二、霍夫圆变换
是OpenCv中用于检测圆的一种方法,使用 HoughCircles函数。
原理:
霍夫圆变换的基本原理和霍夫线变换类似, 只是点对应的二维极径极角空间被三维的圆心点x, y还有半径r空间取代。
对直线来说, 一条直线能由参数极径极角 (r, ) 表示. 而对圆来说, 我们需要三个参数来表示一个圆, 如上文所说现在原图像的边缘图像的任意点对应的经过这个点的所有可能圆是在三维空间有下面这三个参数来表示了,其对应一条三维空间的曲线. 那么与二维的霍夫线变换同样的道理, 对于多个边缘点越多这些点对应的三维空间曲线交于一点那么他们经过的共同圆上的点就越多,类似的我们也就可以用同样的阈值的方法来判断一个圆是否被检测到, 这就是标准霍夫圆变换的原理, 但也正是在三维空间的计算量大大增加的原因, 标准霍夫圆变化很难被应用到实际中:
这里的 表示圆心的位置 (下图中的绿点) 而 r 表示半径, 这样我们就能唯一的定义一个圆了。
实现:
函数为:
void HoughCircles( InputArray image, OutputArray circles,
int method, double dp, double minDist,
double param1 = 100, double param2 = 100,
int minRadius = 0, int maxRadius = 0 );
src_gray: 输入图像 (灰度图)
circles: 存储下面三个参数: x_{c}, y_{c}, r 集合的容器来表示每个检测到的圆.
CV_HOUGH_GRADIENT: 指定检测方法. 现在OpenCV中只有霍夫梯度法
dp = 1: 累加器图像的反比分辨率
min_dist = src_gray.rows/8: 检测到圆心之间的最小距离
param_1 = 200: Canny边缘函数的高阈值
param_2 = 100: 圆心检测阈值.
min_radius = 0: 能检测到的最小圆半径, 默认为0.
max_radius = 0: 能检测到的最大圆半径, 默认为0
int main()
{
RNG rng(12345);
Mat a = imread("8907540_150847495169_2.jpg");
a.resize(350);
imshow("原图", a);
cvtColor(a, a, CV_RGB2GRAY); //转为灰度图
vector<Vec3f> circles;
HoughCircles(a, circles, CV_HOUGH_GRADIENT, 1.5, 10, 200, 100, 0, 0); //检测
cvtColor(a, a, CV_GRAY2BGR);
for (size_t i = 0; i < circles.size(); i++) //开始画圆
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]); //绘制圆心
circle(a, center, 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), -1, 8, 0); //绘制圆
circle(a, center, radius, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3, 8, 0); //依旧是随机颜色
}
imshow("效果图", a);
cvWaitKey(10000);
}
效果图:
OpenCV中的霍夫线变换和霍夫圆变换的更多相关文章
- 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
http://blog.csdn.net/poem_qianmo/article/details/26977557 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...
- 学习 opencv---(13)opencv霍夫变换:霍夫线变换,霍夫圆变换
在本篇文章中,我们将一起学习opencv中霍夫变换相关的知识点,以及了解opencv中实现霍夫变换的HoughLines,HoughLinesP函数的使用方法,实现霍夫圆变换的HoughCircles ...
- 【OpenCV新手教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26977557 作者:毛星云(浅墨) ...
- opencv —— HoughLines、HoughLinesP 霍夫线变换原理(标准霍夫线变换、多尺度霍夫线变换、累积概率霍夫线变换)及直线检测
霍夫线变换的原理 一条直线在图像二维空间可由两个变量表示,有以下两种情况: ① 在笛卡尔坐标系中:可由参数斜率和截距(k,b)表示. ② 在极坐标系中:可由参数极经和极角(r,θ)表示. 对于霍夫线变 ...
- python数字图像处理(15):霍夫线变换
在图片处理中,霍夫变换主要是用来检测图片中的几何形状,包括直线.圆.椭圆等. 在skimage中,霍夫变换是放在tranform模块内,本篇主要讲解霍夫线变换. 对于平面中的一条直线,在笛卡尔坐标系中 ...
- 图像变换 - 霍夫线变换(cvHoughLines2)
霍夫变换是一种在图像中寻找直线.圆及其他简单形状的方法,霍夫线变换是利用Hough变换在二值图像中找到直线. 利用CV_HOUGH_PROBABILISTIC,对应PPHT(累计概率霍夫变换)?这个算 ...
- OpenCV-Python 霍夫线变换 | 三十二
目标 在这一章当中, 我们将了解霍夫变换的概念. 我们将看到如何使用它来检测图像中的线条. 我们将看到以下函数:cv.HoughLines(),cv.HoughLinesP() 理论 如果可以用数学形 ...
- OpenCV 霍夫线变换
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #i ...
- opencv-霍夫直线变换与圆变换
转自:https://blog.csdn.net/poem_qianmo/article/details/26977557 一.引言 在图像处理和计算机视觉领域中,如何从当前的图像中提取所需要的特征信 ...
随机推荐
- 春节过后就是金三银四求职季,分享几个Java面试妙招,轻松搞定HR!
春节过后就是金三银四,分享几个Java面试妙招,轻松搞定HR! 2020年了,先祝大家新年快乐! 今年IT职位依然相当热门,特别是Java开发岗位.软件开发人才在今年将有大量的就业机会.春节过后,金三 ...
- 哈夫曼树 动态数组的使用vector
问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的过程如下: 1. ...
- SpringBoot整合持久层技术--(一)JdbcTemplate
简介: JdbcTemplate是Spring提供的一套JDBC模板框架,利用AOP技术解决直接使用JDBC带来的重复代码问题.它没有MyBatis使用那么灵活,但是却比直接使用JDBC方便得多.Sp ...
- Flink架构,源码及debug
序 工作中用Flink做批量和流式处理有段时间了,感觉只看Flink文档是对Flink ProgramRuntime的细节描述不是很多, 程序员还是看代码最简单和有效.所以想写点东西,记录一下,如果能 ...
- 《京东B2B业务架构演变》阅读
转载:https://mp.weixin.qq.com/s/5xmmuw8O-I_Fi5bzE-_baA?tdsourcetag=s_pcqq_aiomsg 京东 B2B 业务的定位是让各类型的企业都 ...
- 使用Python爬虫整理小说网资源-自学
第一次接触python,原本C语言的习惯使得我还不是很适应python的语法风格.希望读者能够给出建议. 相关的入门指导来自以下的网址:https://blog.csdn.net/c406495762 ...
- PAT (Basic Level) Practice (中文)1057 数零壹 (20 分) (按行输入带空格的字符串)
给定一串长度不超过 1 的字符串,本题要求你将其中所有英文字母的序号(字母 a-z 对应序号 1-26,不分大小写)相加,得到整数 N,然后再分析一下 N 的二进制表示中有多少 0.多少 1.例如给定 ...
- 138.更改session的存储机制
修改session的存储机制: 默认情况下,session数据时存储到数据库中,当然也可以将session数据存储到其他地方.可以通过设置SESSION_ENGINE来更改session的存储位置,这 ...
- 小白月赛22 F: 累乘数字
F:累乘数字 考察点: 思维,高精度 坑点 : 模拟就 OK 析题得侃: 如果你思维比较灵敏:直接输出这个数+ d 个 "00"就行了 当然,我还没有那么灵敏,只能用大数来搞了 关 ...
- Linux下安装python,mysql,redis
linux 安装Python3 1.python下载 请在终端输入如下命令: cd /home wget http://cdn.npm.taobao.org/dist/python/3.6.5/Pyt ...