一 函数介绍
findContours 寻找轮廓
cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
- 参数
第一个参数是寻找轮廓的图像;
第二个参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):
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个点来保存轮廓信息 cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS 使用teh-Chinl chain 近似算法
- 返回值
contour :轮廓要素,列表
hierarchy:轮廓属性
cv2.drawContours 绘制轮廓
drawContours( image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None )
参数解释
. @param image Destination image. 绘制到那张图
. @param contours All the input contours. Each contour is stored as a point vector. 有输入轮廓。每个轮廓都存储为点矢量。 . @param contourIdx Parameter indicating a contour to draw. If it is negative, all the contours are drawn. 指示要绘制的轮廓的参数。如果是negative,则绘制所有轮廓。
. @param color Color of the contours. 绘制线条的颜色 . @param thickness Thickness of lines the contours are drawn with. If it is negative (for example, . thickness=#FILLED ), the contour interiors are drawn. 绘制的线的宽度,如果为<=0,则表示填充 . @param lineType Line connectivity. See #LineTypes . @param hierarchy Optional information about hierarchy. It is only needed if you want to draw only . some of the contours (see maxLevel ). . @param maxLevel Maximal level for drawn contours. If it is 0, only the specified contour is drawn. . If it is 1, the function draws the contour(s) and all the nested contours. If it is 2, the function . draws the contours, all the nested contours, all the nested-to-nested contours, and so on. This . parameter is only taken into account when there is hierarchy available. . @param offset Optional contour shift parameter. Shift all the drawn contours by the specified . \f$\texttt{offset}=(dx,dy)\f$ .
三 简单边缘发现代码实现
代码
import cv2 as cvimport numpy as np# 轮廓发现def contous_image(image): #高斯模糊去除噪点 dst = cv.GaussianBlur(image, (3, 3), 0) gray = cv.cvtColor(dst, cv.COLOR_BGR2GRAY) #图像反转 rev=cv.bitwise_not(gray) ret, binary = cv.threshold(rev, 30, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) cv.imshow("binary", binary) contous, heriachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) for i, contou in enumerate(contous): cv.drawContours(image, contous, i, (0, 0, 255), 2,) cv.imshow("lunkuo", image) for i, contou in enumerate(contous): #-1 表示轮廓填充 cv.drawContours(image, contous, i, (0, 0, 255), -1) cv.imshow("lunkuofill", image)src = cv.imread("yingbi.jpg")cv.imshow("before", src)contous_image(src)cv.waitKey(0)cv.destroyAllWindows()
效果展示
四 基于canny边缘提取的轮廓发现
代码
# -*- coding=GBK -*-import cv2 as cvimport numpy as npdef edge_demo(image): '边缘提取函数' blurred=cv.GaussianBlur(image,(3,3),0) gray=cv.cvtColor(blurred,cv.COLOR_BGR2GRAY) #x Grad xgrad=cv.Sobel(gray,cv.CV_16SC1,1,0) ygrad=cv.Sobel(gray,cv.CV_16SC1,0,1) #边缘提取 # edge_output=cv.Canny(xgrad,ygrad,50,150) edge_output=cv.Canny(gray,30,150) cv.imshow('Canny',edge_output) return edge_output # 轮廓发现 def contous_image(image): binary=edge_demo(image) contous, heriachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) for i, contou in enumerate(contous): cv.drawContours(image, contous, i, (0, 0, 255), 2,) cv.imshow("lunkuo", image) for i, contou in enumerate(contous): #-1 表示轮廓填充 cv.drawContours(image, contous, i, (0, 0, 255), -1) cv.imshow("lunkuofill", image) src = cv.imread("yingbi.jpg") cv.imshow("before", src) contous_image(src) cv.waitKey(0) cv.destroyAllWindows()
效果展示