import cv2
import numpy as np
img=cv2.imread('test.jpg')
imgray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh=cv2.threshold(imgray,127,255,0)
image,contours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.imshow('imageshow',image) # 显示返回值image,其实与输入参数的thresh原图没啥区别
cv2.waitKey()
print(np.size(contours)) # 得到该图中总的轮廓数量
print(contours[0]) # 打印出第一个轮廓的所有点的坐标, 更改此处的0,为0--(总轮廓数-1),可打印出相应轮廓所有点的坐标
print(hierarchy) #打印出相应轮廓之间的关系
img=cv2.drawContours(img,[contours[0]],-1,(0,255,0),10) #标记处编号为0的轮廓,此处img为三通道才能显示轮廓
cv2.imshow('drawimg',img)
cv2.waitKey()
cv2.destroyAllWindows()
标题待测轮廓的图像
cv2.findContours(image, mode, method, contours=None, hierarchy=None, offset=None)
image 代表输入的图片。注意输入的图片必须为二值图片。若输入的图片为彩色图片,必须先进行灰度化和二值化。
mode 表示轮廓的检索模式,有4种:
cv2.RETR_EXTERNAL 表示只检测外轮廓。
cv2.RETR_LIST 检测的轮廓不建立等级关系。
cv2.RETR_CCOMP 建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一 个连通物体,这个物体的边界也在顶层。
cv2.RETR_TREE 建立一个等级树结构的轮廓。
method 为轮廓的近似办法,有4种:
cv2.CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2), abs(y2-y1))<=1。
cv2.CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个 矩形轮廓只需4个点来保存轮廓信息。
cv2.CHAIN_APPROX_TC89_L1 和 cv2.CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法。
cv2.findContours()函数返回两个值,一个是轮廓本身contours,还有一个是每条轮廓对应的属性hierarchy。
contours:
cv2.findContours()函数首先返回一个list,list中每个元素(本例为2个)都是图像中的一个轮廓信息,list中每个元素(轮廓信息)类型为ndarray。len(contours[1]) 表示第一个轮廓储存的元素个数,即该轮廓中储存的点的个数。本例第一个轮廓为矩形,轮廓中有4个点,这是因为当参数mode 设置成: cv2.CHAIN_APPROX_SIMPLE ,轮廓中并不是存储轮廓上所有的点,而是只存储可以用直线描述轮廓的点的个数,比如一个“正立”的矩形,只需4个顶点就能描述轮廓了。
print(type(contours)) # 输出为:
print(type(contours[0])) # 输出为:
print(len(contours)) # 图像中轮廓的数量,输出为:2
print(len(contours[1])) # 轮廓1(矩形)中的元素(点)的数量, 输出为:4
由于我们知道返回的轮廓有两个,因此可通过
cv2.drawContours(img,contours,0,(0,0,255),3)
和
cv2.drawContours(img,contours,1,(0,255,0),3)
分别绘制两个轮廓,关于该参数可参见:cv2.drawContours() 轮廓绘制
hierarchy:
此外,该函数还可返回一个可选的hiararchy结果,这是一个ndarray,其中的元素个数和轮廓个数相同,每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0] ~hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,则该值为负数。
print(hierarchy)
输出:[[[ 1 -1 -1 -1]
[-1 0 -1 -1]]]
下面具体解释下hierarchy输出的矩阵参数的意义:
其输出矩矩阵大小为NXM, 其中N为轮廓的个数,M恒等于4,也就是说每一行的4个数,能够表示出轮廓间的相互关系,那么具体是怎样表示的呢
第一个数:表示同一级轮廓的下个轮廓的编号,如果这一级轮廓没有下一个轮廓,一般是这一级轮廓的最后一个的时候, 则为-1
第二个数:表示同一级轮廓的上个轮廓的编号,如果这一级轮廓没有上一个轮廓,一般是这一级轮廓的第一个的时候,则 为-1
第三个数:表示该轮廓包含的下一级轮廓的第一个的编号,假如没有,则为-1
第四个数: 表示该轮廓的上一级轮廓的编号,假如没有上一级,则为-1
以如下的图片为例:
hierarchy为:
[[[ 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
轮廓0,它的同级下一个的编号为1,第一个参数为1; 因为这一级别的第一个,第二个参数-1;因为不包含子轮廓,所以第三个参数-1;因为处于第一级,其不属于任何别的级别,所以第四个参数为-1
轮廓1,它的同级下一个的编号为4,第一个参数为4; 因为这一级别的上一个的编号为0,第二个参数0;因为包含子轮廓,且子轮廓的第一个编号(当然只包含一个,多个也是同样的道理)为2,所以第三个参数2;因为处于第一级,其不属于任何别的级别,所以第四个参数为-1
轮廓2,它是第二级的最后一个(因为只有一个),所以第一个参数为-1; 它也是第二级的第一个,所以第二个参数为-1;因为包含子轮廓,且子轮廓的第一个编号(当然只包含一个,多个也是同样的道理)为3,所以第三个参数3; 因为处于第二级,其属于上一级的轮廓1,所以第四个参数为1
依次类推 。。。。。轮廓3
轮廓4 它是同一级(第一级)的最后一个,因此第一个参数为-1;因为这一级别的上一个的编号为1,第二个参数1;因为不包含子轮廓,所以第三个参数-1;因为处于第一级,其不属于任何别的级别,所以第四个参数为-1
---------------------
作者:Lecol_leng
来源:CSDN
原文:https://blog.csdn.net/jjddss/article/details/73527990
作者:Daetalus
原文:https://blog.csdn.net/sunny2038/article/details/12889059