1 原理
边界或者轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。
在机器视觉领域最常用的轮廓查找的算法之一是 Moore-Neighbor 算法,像素的摩尔邻域
P
P
P 是与该像素共享顶点或边的
8
8
8 个像素的集合。这些像素即 如下图所示的像素
P
1
P1
P1、
P
2
P2
P2、
P
3
P3
P3、
P
4
P4
P4、
P
5
P5
P5、
P
6
P6
P6、
P
7
P7
P7和
P
8
P8
P8。 摩尔邻域(也称为8 邻域或 间接邻域)是文献中经常出现的一个重要概念。
其大概的原理如下:
- 找到一个黑色像素,并将它定为你的起始像素。(定位一个起始像素可以以多种方式来完成的;我们将从网格的左下角开始,自下而上扫描每一列像素,从最左向右的每列像素,直到遇到一个黑色的像素,我们将其作为我们的起始像素)。
- 每次碰到黑色像素P时,都回溯,即回到之前站立的白色像素,然后以顺时针方向绕过像素 P P P,访问其摩尔邻域中的每个像素,直到击中黑色像素。
- 重复这个过程,当起始像素被第二次访问时算法终止,在整个运行过程走过的黒色像素就是目标的边界像素。走过的黑色像素将成为图案的轮廓。 动画演示,说明 Moore-Neighbor 跟踪如何继续跟踪给定模式的轮廓。(以顺时针方向跟踪轮廓)
2 API
此部分参考了https://blog.csdn.net/sunny2038/article/details/12889059
在 OpenCv 中轮廓查找主要由如下两个 API 来完成。第一个是查找函数 findContours,第二个是绘制轮廓的函数 drawContours。
contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
输入:
- 第一个参数是寻找轮廓的图像,注意是二值图。
- 第二个参数表示轮廓的检索模式,有四种,cv2.RETR_EXTERNAL 表示只检测外轮廓,cv2.RETR_LIST 检测的轮廓不建立等级关系,cv2.RETR_CCOMP 建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。cv2.RETR_TREE 建立一个等级树结构的轮廓。
- 第三个参数method为轮廓的近似办法,cv2.CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过 1,即 m a x ( a b s ( x 1 − x 2 ) , a b s ( y 2 − y 1 ) ) = = 1 max(abs(x1-x2),abs(y2-y1))==1 max(abs(x1−x2),abs(y2−y1))==1,cv2.CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需 4 个点来保存轮廓信息,cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS 使用 teh-Chinl chain 近似算法
输出:
- contours 是轮廓本身。
- hierarchy 是每条轮廓对应的属性。
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])
输入:
- 第一个参数是指明在哪幅图像上绘制轮廓。
- 第二个参数是轮廓本身,在 Python 中是一个 list。
- 第三个参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。thickness 表明轮廓线的宽度。
3 案例
绘制下面所有飞机的轮廓
代码:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
%matplotlib
img_planes = cv.imread('images/planes.png',0)
img = np.zeros((img_planes.shape[0], img_planes.shape[1],3))#查找轮廓,要注意传入的图像一定要是二值图,因为我这里的图片本就是二值化图片,所以不需要二值化
contours, hierarphy = cv.findContours(img_planes, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)#绘制轮廓
cv.drawContours(img, contours,-1,(0,0,255),1)
cv.imshow('img', img)
cv.waitKey(0)
效果:
版权归原作者 进击的南方仔 所有, 如有侵权,请联系我们删除。