一、语法:contours,hierarchy = cv2.findContours(img,mode,method)
参数说明:img为寻找轮廓的图像,且为二值图(黑白图)。
mode为轮廓的检索模式,有四种:cv2.RETR_EXTERNAL只检测外轮廓。cv2.RETR_LIST检测的轮廓不建立等级关系。cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。cv2.RETR_TREE建立一个等级树结构的轮廓。
method为轮廓的近似方法。cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1)) == 1。cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息。
返回值contours表示图像中的所有轮廓的list,np.array类型。
返回值hierarchy可选项,表示轮廓关系的内在索引编号,没对应项的为负值。
import cv2
import numpy as np
img = cv2.imread('contours.bmp') #读取图像
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转为灰度值图
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) #转为二值图
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) #寻找轮廓
cv2.imshow("img",img) #显示原图像
n=len(contours) #轮廓个数
contoursImg=[]
for i in range(n):
length = cv2.arcLength(contours[i], True) #获取轮廓长度
area = cv2.contourArea(contours[i]) #获取轮廓面积
print('length['+str(i)+']长度=',length)
print("contours["+str(i)+"]面积=",area)
temp=np.zeros(img.shape,np.uint8) #生成黑背景
contoursImg.append(temp)
contoursImg[i]=cv2.drawContours(contoursImg[i],contours,i,(255,255,255), 3) #绘制轮廓
cv2.imshow("contours[" + str(i)+"]",contoursImg[i]) #显示轮廓
cv2.waitKey()
cv2.destroyAllWindows()
检测轮廓效果图:
二、实物轮廓检测实例展示
import cv2
import numpy as np
img = cv2.imread('loc3.jpg')
cv2.imshow("img",img) #显示原图像
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转为灰度图
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) #转为二值图
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)#寻找轮廓
mask=np.zeros(img.shape,np.uint8) #生成黑背景,即全为0
mask=cv2.drawContours(mask,contours,-1,(255,255,255),-1) #绘制轮廓,形成掩膜
cv2.imshow("mask" ,mask) #显示掩膜
result=cv2.bitwise_and(img,mask) #按位与操作,得到掩膜区域
cv2.imshow("result" ,result) #显示图像中提取掩膜区域
cv2.waitKey()
cv2.destroyAllWindows()
效果图:
三、不规律轮廓的显示
import cv2
import numpy as np
img1 = cv2.imread('cc.bmp')
cv2.imshow("img",img1) #显示原始图像
img2 = np.copy(img1)
img3 = np.copy(img1)
img4 = np.copy(img1)
img5 = np.copy(img1)
gray = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY) #转为灰度值图
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) #转为二值图
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) #寻找轮廓
x,y,w,h = cv2.boundingRect(contours[0]) #轮廓点
result1 = cv2.rectangle(img1,(x,y),(x+w,y+h),(255,255,255),2) #构造矩形方框
rect = cv2.minAreaRect(contours[0]) #最小面积方框
points = cv2.boxPoints(rect)
points = np.int0(points) #取整
result2=cv2.drawContours(img2,[points],0,(255,255,255),2)
(x,y),radius = cv2.minEnclosingCircle(contours[0]) #寻找中心点,半径
center = (int(x),int(y))
radius = int(radius)
result3 = cv2.circle(img3,center,radius,(255,255,255),2) #绘制圆
ellipse = cv2.fitEllipse(contours[0]) #寻找椭圆
result4 = cv2.ellipse(img4,ellipse,(0,255,0),3) #绘制椭圆
area,trgl = cv2.minEnclosingTriangle(contours[0]) #寻找三角形
for i in range(0, 3): #绘制三角形
result5 = cv2.line(img5, tuple(trgl[i][0]), tuple(trgl[(i + 1) % 3][0]), (255,255,255), 2)
cv2.imshow("result1",result1) #显示结果图像
cv2.imshow("result2",result2)
cv2.imshow("result3",result3)
cv2.imshow("result4",result4)
cv2.imshow("result5",result5)
cv2.waitKey()
cv2.destroyAllWindows()
效果图:
四、CT异常物体检测实例
import cv2
import numpy as np
img = cv2.imread('ct.png')
cv2.imshow("img",img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
ct=contours[2] #coutours[0]、coutours[1]是左侧字母R
mask = np.zeros(img.shape,np.uint8)
mask = cv2.drawContours(mask,[ct],-1,(255,255,255),-1) #生成掩膜
result = cv2.bitwise_and(img,mask) #按位与,获取掩膜感兴趣区域
cv2.imshow("result",result)
cv2.waitKey()
cv2.destroyAllWindows()
效果图: