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 一.引言 在图像处理和计算机视觉领域中,如何从当前的图像中提取所需要的特征信 ...
随机推荐
- JN_0017:在当前目录运行CMD
运行npm的时候,每次都要cd到目录,很麻烦,所以总结了三种在当前目录下直接打开cmd窗口的方法,供以后开发时参考,相信对其他人也有用. 方法一 在当前目录按住shift再右键. 会看到右键菜单里有一 ...
- Redis入门-02-CentOS7环境搭建
CentOS7下redis安装过程,安装后需要开启端口号6379 #下载 wget http://download.redis.io/releases/redis-3.2.4.tar.gz #解压 t ...
- 安装MySQL被提示缺少msvcr120.dll,msvcp120.dll或提示0xc00007b错误
踩坑经历: 我的电脑昨天重装了win10系统,在安装MySQL时被提示缺少msvcr120.dll,我去下载msvcr120.dll后放入System32中,又被提示缺少msvcp120.dll,然后 ...
- 《京东B2B业务架构演变》阅读
转载:https://mp.weixin.qq.com/s/5xmmuw8O-I_Fi5bzE-_baA?tdsourcetag=s_pcqq_aiomsg 京东 B2B 业务的定位是让各类型的企业都 ...
- 0009 基于DRF框架开发(02 创建模型)
上一节介绍了DRF开发的基本流程,共五个步骤: 1 创建模型 2 创建序列化器 3 编写视图 4 配置URL 5 运行测试 本节主要讲解创建模型. 构建学校,教师,学生三个模型,这三个模型之间的关系是 ...
- Tomcat 后台war部署上传shell
tomcat的后台登录的两个目录为: /admin /manager/html 如果版本过高,只有采用弱密码的方式进后台: 有些tomcat采用默认的用户名和密码(用户名:admin,密码:空): 或 ...
- Milestone
为什么开博客? 事情要从一只蝙蝠说起... 准备用博客做什么? 记录自己在开发中遇到的issue以及解决的思路:记录一些读书笔记以便温故:练习如何制造仪式感,ect. ...
- python3练习100题——045
题目:统计 1 到 100 之和. sum(range(1,101)) 题目太容易了,我都不想用迭代浪费时间. 觉得这100道题难度设计越来越不合理.
- base(根URL)
指定用于一个文档中包含的所有相对 URL 的根 URL.一份中只能有一个 <base> 元素. 可以通过使用 document.baseURI 的 JS 脚本查询 属性 包含全局属性 hr ...
- <input type="file">文件上传
<input> type 类型为 file 时使得用户可以选择一个或多个元素以提交表单的方式上传到服务器上,或者通过 Javascript 的 File API 对文件进行操作 . 常用i ...