边界框、最小矩阵框和最小闭圆的轮廓
- 正方形轮廓找起来比较简单,那么不规则图像的轮廓应该如何找呢?现实的应用会对目标的边界框、最小矩形面积、最小闭圆特别感兴趣。将cv2.findContours函数与少量的OpenCV的功能相结合就能非常容易地实现这些功能:
- 代码示例 3_4.py
![6c8141bfc8d8b76827e7727b3acde8ac.png](https://i-blog.csdnimg.cn/blog_migrate/1c023e01c8a0a6c4442669b6c0fa82ab.png)
![20c6824efcc679fa3e5a7fcb1691bfbe.png](https://i-blog.csdnimg.cn/blog_migrate/eec13d40442a22ec173b13e10401573c.png)
![76070727b207486485e166353bf63527.png](https://i-blog.csdnimg.cn/blog_migrate/6faa548a76885a3a514a7f3c6cf61a31.jpeg)
3.代码解释
- cv2.pyrDown():将图像尺寸缩小,分辨率降低,对图像进行滤波,再进行下采样。同样的还要一个pyrUp()是将图像尺寸变大,分辨率不变。
- cv2.boundingRect():用最小的矩形把找到的形状圈起来,返回值中x,y是左上角的坐标,w和h是矩形的宽和高。
- cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2):img是画矩形的图像,第二个参数为矩形左上角的值,第三个为右下角的坐标值,x指的是列,y指的是行。第四个参数为画线的颜色,最后一个为线宽。
- cv2.minAreaRect():找最小外接矩形,返回值rect是大小为2*2,分别对应于最小外接矩形的中心(x,y),(宽度,高度),旋转角度。计算出来的顶点坐标为浮点型,要将其转换为整型的像素坐标。下面链接里的图可以更好解释角度的问题。
![f7e01dbde4e0d886ec7cc072278bdb62.png](https://i-blog.csdnimg.cn/blog_migrate/99d7b3cc5e2fa484b69431e9aef61ecc.png)
- cv2.boxPoints():获取绘制图形的信息,分别是中心坐标,宽度,高度,旋转角度。
- cv2.drawContours(img,[box],0,(0,0,255),3):该函数的第二个参数接收一个保存着轮廓的数组,从而可以在一次操作中绘制一系列轮廓,因此如果只有一组点表示多边形轮廓,就需要放到一个数组里,第三个参数为所要绘制的轮廓的索引,-1为绘制所有的轮廓,否则只会绘制轮廓组中指定的轮廓。3为线宽
- cv2.minEnclosingCircle():返回一个二元组,第一个元素为圆心坐标组成的元组,第二个元素为圆的半径值。
- cv2.circle():参数分别是图像,圆心,半径,颜色,最后一个参数为-1时,表示把整个圆填满,为正数时表示线宽。
凸轮廓与Douglas-Peucker算法
- cv2. approxPloyDP是一个OpenCV函数,它用来计算近似的多边形框。该函数有三个参数,第一个参数为“轮廓',第二个参数为“ε值”,它表示源轮廓与近似多边形的最大差值(这个值越小,近似多边形与源轮廓越接近),第三个参数为“布尔标记”,它表示这个多边形是否闭合。
- ε是为所得到的近似多边形周长与源轮廓周长之间的最大差值,这个差值越小,近似多边形与源轮廓就越相似。
- 在了解了ε值是什么之后,需要得到轮廓的周长信息来作为参考值。这可通过OpenCV的cv2.arcLength 函数来完成。
- 源轮廓、近似多边形和凸包的不同,如下图所示,凸包包围着整个物体,最里面的为近似多边形,在这两者之间的是源轮廓,它主要由弧线构成。
![1ce95f6341b4ee8c249699ff9af1837a.png](https://i-blog.csdnimg.cn/blog_migrate/e9649111b1b31b215a3e0ce3b969df8a.png)
直线检测
- Hough变换是直线和形状检测的理论基础。直线检测可以通过HoughLines和HoughLinesP函数来完成。两者差别是,第一个函数使用标准的Hough变换,第二个函数使用概率Hough变换(因此名称里有一个P)。
- HoughLinesP函数之所以称为概率版本的Hough变换是因为它只通过分析点的子集并估计这些点都属于一条直线的概率,这是标准Hough变换的优化版本。该函数的计算代价会少一些,执行会变得更快。
- 注意,HoughLines函数会接收一个由Canny边缘检测滤波器处理过的单通道二值图像。不一定需要Canny滤波器,但是一个经过去噪并只有边缘的图像当作Hough变换的输入会很不错,因此使用Canny滤波器是一个普遍的惯例。
- 参数介绍
- minLineLength:设置最小的直线长度,更短的直线会被消除。
- maxLineGap:最大线段间隙,一条线段间隙大于设定的值会被认为两条线段
- 下面解释HoughLinesP的几个参数:需要处理的图像;线段的几何表示rho和theta,一般分别取1和np.pi/180;阈值,低于该阈值的直线会被忽略,Hough变换可以理解为投票箱和投票数之间的关系,每个投票箱代表一个直线,投票数达到阈值的直线会被保留,其他的会被删除;前面已经介绍过的minLineLength和maxLineGap。
- cv2.line():参数分别是画线的图像,直线起点,直线终点,颜色,线宽。
5.代码示例
![efd221c68843ff484549de444d55e53a.png](https://i-blog.csdnimg.cn/blog_migrate/8f7744ea0963d9cc8bacf8c20e31a105.jpeg)
6.结果
通过输出lines.shape查看找到的直线条数,找到直线为152条,示例中代码循环中只画出了一条直线。
![be350e97d8e513f3b5e70b6e5cb3f3f1.png](https://i-blog.csdnimg.cn/blog_migrate/0bb7a58a101743507479404d11f6cd49.png)
![c32c1ed4b6c3877ba1b39c046717b522.png](https://i-blog.csdnimg.cn/blog_migrate/56eb64d774983943da0ba1e392428e61.png)
这个是将所有直线画出来的结果。
![bf799bc4a169a88de5592d86fe55a1e3.png](https://i-blog.csdnimg.cn/blog_migrate/bac9625e874f58021a9809da7abc4a88.png)
圆检测
- OpenCV的HoughCircles函数可用来检测圆,它与使用HoughLines函数类似。像用来决定删除或保留直线的两个参数minLineLength和maxLineGap 一样,HoughCircles 有一个圆心间的最小距离和圆的最小及最大半径。
- 代码示例
![b689fbdbdf2634807fec1a51dae75b51.png](https://i-blog.csdnimg.cn/blog_migrate/80670319f3b315c19590ea2ad22c6b32.jpeg)
3.代码解释
- cv2.medianBlur():中值滤波,模板大小这里用的是5*5,最后显示的图像中滤波后的img比原图要清晰很多。
- cv2.HoughCircles():检测圆。参数分别是,输入图像;检测用的方法,目前只有这一种利用梯度的方法可实现;累加器图像的反比分辨率,为1时代表和输入图像分别率相同,为2时代表累加器只有原图像height,width的一半;允许的圆心之间的最小距离,如果距离太小,会产生很多相交的圆,如果距离太大,则会漏掉正确的圆;param1,canny检测的双阈值中的高阈值,低阈值是它的一半;圆心检测阈值param2,最小投票数(基于圆心的投票数),就类似于直线检测中的阈值minLineLength,它决定了某组参数是不是有圆;能检测到的最小圆半径;能检测到的最大圆半径。
- cv2.circle():参数分别是图像,圆心,半径,颜色,线宽。