前言
- 需要下载安装OpenCV工具包的朋友,请前往 此处 ;
- 系统要求:Windows系统,LabVIEW>=2018,兼容32位和64位。
imgproc 基础操作(下)
8. 霍夫检测
霍夫检测,是一种用于检测图像中直线、圆等几何形状的方法。
目前包含以下方法:
函数 | 功能 |
---|---|
HoughLines | 霍夫直线检测。输入图像,返回直线数组,每条直线用(rho,theta)表示。 rho是原点到直线的垂线距离,theta是垂线的仰角(弧度),所以(rho,theta)相当于垂足的极坐标。 |
HoughLinesPointSet | 霍夫散点直线查找。输入坐标点数组,返回直线数组,每条直线用(votes,rho,theta)表示。 votes是票数,表示有多少个散点落在该直线上。rho,theta 含义同上。 |
HoughLinesP | 霍夫线段检测。输入图像,返回线段数组,每条线段包含其两个端点坐标(pt1,pt2)。 |
HoughCircles | 霍夫圆检测。输入图像,返回圆数组,每个圆包含圆心坐标和半径(center,radius)。 |
- 例8-1:霍夫直线检测
- 在检测之前,一般需要对图像进行滤波降噪(blur)和边缘检测(Canny),从而保证直线检测效果;
- HoughLines 参数:
- rho:表示直线的 rho 分辨率(精度),默认为 1;
- theta:表示直线的 theta 分辨率,默认为 1/180 弧度;
- threshold:累积器阈值,只有累积值大于该阈值的直线才会被认为是有效的;
- srn 和 stn:分别代表 rho 缩放因子 和 theta 缩放因子,默认都为0;
- min_theta 和 max_theta:顾名思义,分别代表 theta 的最小值和最大值,默认范围 0 - π;
- 上图中的可视化过程已封装成子VI:draw_lines.vi,其内部算法如下图。实现方法不唯一。
- 本例先使用 LabVIEW 自带的 Polar To Re/Im 将每个极坐标转换成垂足的(X,Y)坐标,然后从垂足出发,朝两端各延申1000单位,计算得到直线上距离较远的两点,最后将这两点输入给 line 函数进行绘制。
- 例8-2:霍夫线段检测
- 与直线检测类似,线段检测也需要先降噪和边缘检测。线段检测返回端点,可以直接绘图,可视化相对简单。
- HoughLinesP 参数:
- rho、theta、threshold:同上(HoughLines);
- minLineLength:最小线段长度;
- maxLineGap:最大线段跨度,代表同一直线上的相邻点之间的最大允许间隔;
- 例8-3:霍夫圆检测
- 霍夫圆检测也需要降噪滤波,但一般不用边缘检测,因为它自带梯度计算模式;
- HoughCircles 参数:
- method:检测方法,默认为 HOUGH_GRADIENT ,梯度检测方式;
- dp:累加器精度和图像精度之比的倒数。例如,dp=1代表累加器分辨率和输入图像分辨率相同;dp=2时累加器分辨率是输入图像的一半;
- minDist:圆心与圆心之间的最小距离,用于筛除掉过于重合的圆;
- param1:相当于 Canny 检测的高阈值,低阈值自动设为 param1 的一半;
- param2:累加器阈值,越小检测到的圆越多,越大检测到的圆越严格精确;
- minRadius 和 maxRadius:顾名思义,最小半径和最大半径;
9. 滤波与模糊
图像滤波的原理,是定义一个边长为 K (奇数)的小窗口,称为 “核”,令其在源图像上逐个像素地滑动。每滑动到一个位置,对小窗口遮罩的所有像素值进行某种运算,得到一个新的像素值,该值就作为此时小窗口中心点所在像素的滤波结果。当小窗口中心滑过源图像所有像素后,所有新的像素值就组成了滤波后的图像。
当小窗口中心沿着图像边界滑动时,会有一部分窗格落在图像边界之外,所以滤波器一般都要指定采用哪种 边界填充 方案。
根据 滤波核 与 滤波算法 的不同,图像滤波呈现的效果也不同。低通滤波器的效果是平滑图像、除噪声;高通滤波器则会锐化图像。因此,滤波的概念比模糊更广泛,模糊本质上是一种低通滤波过程。
OpenCV中,用于实现模糊、滤波,以及生成滤波核(也叫卷积核)的函数总结如下:
函数 | 功能 |
---|---|
blur | 均值模糊 |
medianBlur | 中值模糊 |
GaussianBlur | 高斯模糊 |
stackBlur | StackBlur 算法,一种高斯模糊的快速近似算法,计算成本低 |
filter2D | 通用2D图像线性滤波器 |
sepFilter2D | 可分离的线性滤波器 |
bilateralFilter | 双边滤波器,一种非线性滤波器 |
boxFilter | 方盒滤波器,计算局部均值 |
sqrBoxFilter | 类似方盒滤波器,但计算局部平方和,并归一化 |
getGaborKernel | 生成Gabor滤波核 |
getGaussianKernel | 生成高斯滤波核 |
getDerivKernel | 生成导数滤波核,两个方向kx,ky |
getStructuringElement | 生成结构化元素 |
其他 | 除上述之外,二值图的腐蚀、膨胀、开闭运算,梯度计算,照片降噪等等,也都算是滤波的一种。 |
上述函数在 imgproc 选板中的位置如下图:
- 例9-1:中值模糊 与 高斯模糊
- ksize 是滤波核的边长,必须是奇数;高斯核允许 ksize 的x,y方向尺寸不一样;
- sigmaX 和 sigmaY 是高斯核在x,y方向上分布的 σ 值(标准差);
- borderType 是边界填充类型;medianBlur不用指定borderType ,它默认采用 BORDER_REPLICATE;
- 例9-2:生成高斯核,再用以 filter2D 进行滤波
- getGaussianKernel 只能生成一维高斯核(列向量),传入 filter2D 后只能进行 y 方向的滤波。如果需要二维高斯核,可以调用2次 getGaussianKernel 生成2个一维高斯核,再用 core 模块的 mulTransposed 函数计算得到二维高斯核;
- ddepth 是目标图像深度,-1代表与源图像相同;
- anchor 是卷积核的锚点,(-1,-1)代表中心点;
- delta 是偏移量,即滤波之后统一增加的值;
- borderType 是边界填充类型。
- 例9-3:生成X、Y两个方向的 导数 滤波核,再用以 sepFilter2D 进行滤波
- getDerivKernel 参数:dx,dy 分别是x,y方向的求导阶数;ksize 是核尺寸;normalize 代表是否归一化;ktype 是核数据类型;
- sepFilter2D 参数:同上文 filter2D 函数;
- 此例是典型的高通滤波。像素变化不大的区域,导数几乎为0,所以是黑色;轮廓边缘导数较大,所以被增强;
- 例9-4:bilateralFilter 双边滤波
双边滤波器在每个像素点上应用一个卷积核,卷积核的权重由 空间 高斯函数和 颜色 高斯函数共同决定。空间高斯函数考虑像素间的空间距离,而颜色高斯函数考虑像素间的颜色差异。这使得双边滤波在平滑图像的同时能够保持边缘的清晰度,非常适合用于去除噪声和保持图像特征。
- d 是滤波器直径,相当于上述卷积核尺寸;
- sigmaColor 是颜色域的高斯分布 sigma 值;
- sigmaSpace 是空间域的高斯分布 sigma 值;
- borderType 是边界填充类型。
10. 拟合与包围
拟合:指的是应用回归算法确定一条直线或曲线,使尽可能多的散点落在线上或线的附近。
包围:指的是寻找能够完全包围所有散点的最小几何图形。
相关的 OpenCV 函数总结如下:
函数 | 功能 |
---|---|
fitLine2D | 平面直线拟合 |
fitLine3D | 空间直线拟合 |
fitEllipse | 椭圆拟合,基于最小二乘法 |
fitEllipseAMS | 椭圆拟合,基于近似均方 |
fitEllipseDirect | 椭圆拟合,基于直接最小二乘法 |
boundingRect | 计算点集的外接矩形,返回 Rect 对象 |
minAreaRect | 计算点集的最小外接矩形,返回旋转矩形 RotatedRect 对象 |
minEnclosingCircle | 计算点集的最小外接圆,返回圆心和半径 |
minEnclosingTriangle | 计算点集的最小外接三角形,返回三角形顶点坐标 |
上述函数在 imgproc 选板中的位置如下图:
- 例10-1:fitLine2D 直线拟合
- 如下图,在 300x300 的背景下,用实心圆描出所有散点,然后将散点数组输入给 fitLine2D 进行拟合;
- 距离算法 distType 选择 DIST_L2,其余参数不连(使用默认),拟合结果由(vx,vy,x0,y0)描述。其中 (vx, vy)是直线的方向向量,(x0, y0) 是直线上一点,可以据此画出直线线段;
- 如果使用 fitLine3D 拟合空间直线,那么将返回 6 元素的结果(vx,vy,vz,x0,y0,z0),包含空间方向向量(vx,vy,vz),以及空间直线上一点(x0,y0,z0)。
- 例10-2:fitEllipse 椭圆拟合
- 如下图。fitEllipse 返回的结果是椭圆的 外接旋转矩形,需要经过转换才能用 ellipse 画图。
- 例10-3:针对相同的点集,分别做 boundingRect 与 minAreaRect 包围
- boundingRect 返回 Rect,可以直接用 rectangle 画图;
- minAreaRect 返回 RotatedRect,可以先用 boxPoints 提取其4个顶点,然后用 polylines 画成闭合四边形;
总结
- 本系列博文作为LabVIEW工具包—OpenCV的教程,将以专栏的形式陆续发布和更新。
- 对工具包感兴趣的朋友,欢迎下载试用:秣厉科技 - LabVIEW工具包 - OpenCV
- 各位看官有什么想法、建议、吐槽、批评,或新奇的需求,也欢迎留言讨论。