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 一.引言 在图像处理和计算机视觉领域中,如何从当前的图像中提取所需要的特征信 ...
随机推荐
- 复原IP地址
这道题有点不好理解 export default (str) => { // 保存所有符合条件的IP地址 let r = [] // 分四步递归处理ip分段 let search = (cur, ...
- vim和emacs
vim和emacs 在编程界一直有两大神器的传说.这两大神器一个是emacs,一个是vim.一个是神的编辑器,一个是编辑器之神. 程序员的圈子里面也一直流传着一个段子,说是世界上的程序员分为三种.使用 ...
- source、sh、./执行脚本对变量的影响
shell脚本中的变量: local一般用于局部变量声明,多在在函数内部使用. shell脚本中定义的变量是global的,其作用域从被定义的地方开始,到shell结束或被显示删除的地方为止. she ...
- jsp环境搭建
jsp开发环境需要JDK与Tomcat,需先下载JDK组件与tomcat组件 JDK地址:https://www.oracle.com/technetwork/java/javase/download ...
- H5-当你想在出现遮罩的时候,锁住用户的滚动行为,你可以这么做。
<div class="mask"> <div class="content">我是弹框</div> </div> ...
- ASP.NET常用内置对象(一)Request
用来获取客户端在请求一个页面或传送一个Form是提供的所有信息.它包括用户的HTTP变量.能够识别的浏览器信息.存储客户端的Cookie信息和请求地址等. Request对象是System.Web.H ...
- 本机添加多IP绑定网站
查询IP 显示为1个IP 点击更改适配器 点击高级 进行添加IP 点击添加 ipconfig 查看效果 注~!:在IIS中可以在这里添加多IP然后绑定
- 缓存 - 数据缓存 - IndexedDB - Dexie.js
Classes Dexie DexieError Collection and():Add JS based criteria to collection(向集合添加基于JS的条件) delete() ...
- vue中jquery详情
jQuery基本语法 $(selector).action() 基本选择器:$("#id") 标签选择器:$("tagName") class选择器:$(&qu ...
- 2018护网杯easy_tornado(SSTI tornado render模板注入)
考点:SSTI注入 原理: tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且 ...