一 函数介绍
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$ exttt{offset}=(dx,dy)f$ .
三 简单边缘发现代码实现
代码
import cv2 as cv import 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 cv
import numpy as np
def 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()
效果展示