前面学习直线和圆的查找,如果要找一些不规则的轮廓,怎么办呢?其实OpenCV里提供了findContours函数来实现相关的功能,这个函数定义如下:
参数
第一个参数是寻找轮廓的图像;
第二个参数表示轮廓的检索模式,有四种(本文介绍的都是新的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 近似算法
cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。
绘制轮廓的drawContours函数定义如下:
参数:
image - 目标图像
contours - 所有的输入轮廓,每个轮廓为点矢量(a point vector)/点向量 形式,与findcontours中的返回值 contours 的列表list形式一致(具体详见代码)
contourIdx - 指定轮廓列表的索引 ID(将被绘制),若为负数,则所有的轮廓将会被绘制。
color - 绘制轮廓的颜色。
thickness - 绘制轮廓线条的宽度,若为负值或CV.FILLED则将填充轮廓内部区域
lineType - Line connectivity,(有的翻译线型,有的翻译线的连通性)
hierarchy - 层次结构信息,与函数findcontours()的hierarchy有关
maxLevel - 绘制轮廓的最高级别。若为0,则绘制指定轮廓;若为1,则绘制该轮廓和所有嵌套轮廓(nested contours);若为2,则绘制该轮廓、嵌套轮廓(nested contours)/子轮廓和嵌套-嵌套轮廓(all the nested-to-nested contours)/孙轮廓,等等。该参数只有在层级结构时才用到。
offset - 按照偏移量移动所有的轮廓(点坐标)。
用下面的例子来演示:
#python 3.7.4,opencv4.1
#蔡军生 https://blog.csdn.net/caimouse/article/details/51749579
#
import cv2
import numpy as np
from scipy import signal
import math
#图片的路径
imgname = "7board1.png"
#读取图片
image = cv2.imread(imgname, cv2.IMREAD_COLOR)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#图片的高度和宽度
h,w = image.shape[:2]
print('imagesize={}-{}'.format(w,h))
img_blur = cv2.GaussianBlur(gray,(3,3),0.5)
cv2.imshow("img_blur",img_blur)
#
img_bin = cv2.Canny(img_blur,50,200)
cv2.imshow("img_bin",img_bin)
#查找,绘制
contours , hierarchy = cv2.findContours(img_bin , cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
print(len(contours))
cv2.drawContours(image,contours,-1,(0,0,255),2)
cv2.imshow("Image",image)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果输出如下:
高斯平滑后照片
Canny处理后二值图
原图上画出识别的轮廓边缘
https://blog.csdn.net/caimouse/article/details/51749579
转载:https://blog.csdn.net/caimouse/article/details/102394390