findContours函数详细解析
1: image, cnts, hierarchy = cv2.findContours(a,b,c)//寻找图形中的轮廓
传入的参数:
a:传入的图像(二值化图像)
b:轮廓的检索模式,一般是检测外轮廓cv2.RETR_EXTERNAL
c:轮廓的近似方法有两种:(近似都是用近似矩形的方法,c不同的取值只是存储近似矩形的方法不同)
①CV_CHAIN_APPROX_SIMPLE:
一般是保留轮廓的终点坐标:近似矩形的左上角顶点坐标以及宽和高(x,y,w,h):
②CV_CHAIN_APPROX_NONE:
存储所有的轮廓点,相邻的两个点的像素位置差不超过1
函数返回值:
image:处理过的图像(就是原本的图像,findcontous函数不改变你传入的图像)
cnts:轮廓的点集列表,下文细说
hierarchy:轮廓的层次结构,下文细说
cnts解析:
cnts代表的是找到的轮廓的点集的集合,它是一个numpy中的列表结构。你也可以把它理解为一个存储着图像中每个轮廓的数组,就像这样:
a = np.size(cnts) //a就是图像中所有轮廓的数量。
cnts[i] //表示拿出图象中第i个轮廓。至于一个图像中那么多轮廓的索引如何规定,那是计算机的事情
只不过这个数组的每个位置存储的是图片中的一小部分图像(因为画一个轮廓只是画了整个图片的一部分,上文提到,画轮廓是以近似矩形的方式画的,然后cnts“数组”中的每个位置存储的就是这样一个被矩形围起来的图像的坐标)。如:
(注意,findContours只是找轮廓,不是画轮廓,画轮廓是drawContours函数,只不过draw函数是以find函数为基础进行画的)
这个图片被画出了10个轮廓,那么cnts的存储情况就是这样:
由图可见,cnts存储了10个“元素”,每个“元素”都是一个轮廓包围的图像的坐标。
hierarchy解析(重要性不如cnts)
hierarchy存储的是轮廓之间的层级关系,hierarchy是一个N*M大小的矩阵,N就是轮廓数量,M固定等于4。如:
[[[ 1 -1 -1 -1] #轮廓0
[ 4 0 2 -1] #轮廓1
[-1 -1 3 1] #轮廓2
[-1 -1 -1 2] #轮廓3
[-1 1 -1 -1]]] #轮廓4
由这段数据可知,这是五个轮廓,每个轮廓都有一个属于自己的层级关系,可以表示为[a,b,c,d]:
a:表示同级轮廓的下个轮廓的编号,如果没用下一个,a=-1
b:表示同级轮廓的上个轮廓的编号,如果没有上一个,b=-1
c:表示该轮廓包含的下一级轮廓的第一个的编号,如果没有,c = -1
d: 表示该轮廓的上一级轮廓的编号,如果没有,d = -1
每个轮廓的编号是计算机分配的(现在个人是这么理解的),分配好之后就可以得出每个轮廓对应的层次矩阵
轮廓0,它的同级下一个的编号为1,第一个参数为1; 因为这一级别的第一个,第二个参数-1;因为不包含子轮廓,所以第三个参数-1;因为处于第一级,其不属于任何别的级别,所以第四个参数为-1
轮廓1,它的同级下一个的编号为4,第一个参数为4; 因为这一级别的上一个的编号为0,第二个参数0;因为包含子轮廓,且子轮廓的第一个编号(当然只包含一个,多个也是同样的道理)为2,所以第三个参数2;因为处于第一级,其不属于任何别的级别,所以第四个参数为-1…之后以此类推
若有错误,欢迎指正