文章目录
- 效果演示
一、霍夫变换-直线
Hough Line Transform用来做直线检测
前提条件 – 边缘检测已经完成
- 平面空间(x,y)到极坐标空间转换;
- 对极坐标进行变换,转化为θ与R的关系
对于任意一条直线上的所有点来说,变换到极坐标中,从[0~360]空间,可以得到r的大小,属于同一条直线上点在极坐标空
标准的霍夫变换 cv::HoughLines 从平面坐标转换到霍夫空间,最终输出是
void HoughLines( InputArray image, 输入图像,必须8-bit的灰度图像
OutputArray
lines, 输出的极坐标来表示直线
double
rho, 极坐标素扫描步长
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
);
霍夫变换直线概率 cv::HoughLinesP最终输出是直线的两个点 。
void HoughLinesP(
InputArray image, 输入图像,必须8-bit的灰度图像
OutputArray lines, 输出的极坐标来表示直线
double rho, 极坐标像素扫描步长
double theta, 极坐标角度步长,一般取值CV_PI/180
int threshold, 阈值,多少交点的极坐标点才被看成是直线
double minLineLength = 0, 最小直线长度
double maxLineGap = 0 ); 最大间隔
头文件 quick_opencv.h:声明类与公共函数
主函数调用该类的公共成员函数
源文件 quick_demo.cpp:实现类与公共函数
效果演示
二、霍夫圆检测
算法详情见:霍夫圆检测 官方给出了好的示例。
对直线来说,一条直线能由极径极角 表示,而对于圆来说,我们需要三个参数:圆心,半径 。
笛卡尔坐标系中圆的方程为:
这就意味着每一组(a,b,r)代表一个通过点(x0,y0)的圆。
对于一个给定点(x0,y0),我们可以在三维直角坐标系中,绘出所有通过它的圆。最终我们将得到一条三维的曲线。
由于霍夫线变换圆检测对噪声比较敏感,所以首先要对图像做中值滤波,而且需要更多的检测计算消耗。OpenCV 霍夫圆变换对标准霍夫圆变换做了运算上的优化。它采用的是 “霍夫梯度法”。
基于效率考虑,Opencv中实现的霍夫变换圆检测是基于图像梯度的实现,分为两步:
1. 检测边缘,发现可能的圆心
2. 基于第一步的基础上从候选圆心开始计算最佳半径大小
霍夫梯度法的原理
估计圆心
- 把原图做一次 Canny 边缘检测,得到边缘检测的二值图。
- 对原始图像执行一次 Sobel 算子,计算出所有像素的邻域梯度值。
- 初始化圆心空间 N(a,b),令所有的 N(a,b)=0。
- 遍历 Canny 边缘二值图中的所有非零像素点,沿着梯度方向 ( 切线的垂直方向 )画线,将线段经过的所有累加器中的点 (a,b) 的 N(a,b)+=1。
void HoughCircles( InputArray image, 输入图像 ,必须是8位的单通道灰度图像
OutputArray
circles, 输出结果,发现的圆信息
int
method, HOUGH_GRADIENT
double
dp, dp = 1 累加器图像的反比分辨率
double
minDist=src_gray.rows/8, 检测到圆心之间的最小距离,否则认为是同心圆-
double
param1 = 100, canny edge detection low threshold
double
param2 = 100, 中心点累加器阈值 – 候选圆心
int
minRadius = 0, 能检测到的最小圆半径, 默认为0
int
maxRadius = 0 能检测到的最大圆半径, 默认为0
);
我们也可以使用图像矩来检测圆形