2022-11-11 来源:华纳网 责任编辑:谷雨老师 人气:
核心提示:本课内容: 大家好,欢迎来到谷雨课堂 本节, 我们来识别图片中的各种形状, 首先我们把图像进行上节所述的二值化, 然后使用opencv提供的 findContours方法进行轮廓的查找, 最后使用approxPolyDP进行多边形的拟合, 得到多边形的边数, 进而判断出是什么形

本课内容:

大家好,欢迎来到谷雨课堂

 

本节,
我们来识别图片中的各种形状,
首先我们把图像进行上节所述的二值化,
然后使用opencv提供的findContours方法进行轮廓的查找,
最后使用approxPolyDP进行多边形的拟合,
得到多边形的边数,
进而判断出是什么形状,
 
以下是本节的全部源代码:
 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
#No.33 视觉检测之寻找各种形状import cv2 as cvimport numpy as np
class GuyuShapeAnalysis:def __init__(self):        self.shapes = {'triangle': 0, 'rectangle': 0,  'circles': 0}
def analysis(self, frame):        h, w, ch = frame.shape        result = np.zeros((h, w, ch), dtype=np.uint8)
        gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# 二值化图像        ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
        cv.imshow("gray",gray)        cv.imshow("threshold",binary)        cv.imshow("orgi", frame)
#轮廓提取#CV_RETR_EXTERNAL:只有最外层轮廓#压缩轮廓,把横竖撇捺都压缩得只剩下顶点        contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
for cnt in range(len(contours)):
# 提取与绘制轮廓            cv.drawContours(result, contours, cnt, (0, 255, 0), 2)
# 轮廓逼近# arcLength 计算轮廓周长            epsilon = 0.01 * cv.arcLength(contours[cnt], True)
#多边拟合函数#approxPolyDP 把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合            approx = cv.approxPolyDP(contours[cnt], epsilon, True)
# 分析几何形状            corners = len(approx)            shape_type = ""if corners == 3:                count = self.shapes['triangle']                count = count+1                self.shapes['triangle'] = count                shape_type = "三角形"if corners == 4:                count = self.shapes['rectangle']                count = count + 1                self.shapes['rectangle'] = count                shape_type = "矩形"if corners >= 10:                count = self.shapes['circles']                count = count + 1                self.shapes['circles'] = count                shape_type = "圆形"            print("find ",shape_type)        print(self.shapes)
return self.shapes

#读取图片src = cv.imread("1.jpg")
#分析图片ld = GuyuShapeAnalysis()ld.analysis(src)
#显示并等待退出cv.waitKey(0)cv.destroyAllWindows()


 

扩展阅读:

findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset = Point());

参数1:单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像;

 

参数2:contours定义为“vector<vector<Point>> contours”,是一个双重向量(向量内每个元素保存了一组由连续的Point构成的点的集合的向量),每一组点集就是一个轮廓,有多少轮廓,contours就有多少元素;

 

参数3:hierarchy定义为“vector<Vec4i> hierarchy”,Vec4i的定义:typedef Vec<int, 4> Vec4i;(向量内每个元素都包含了4个int型变量),所以从定义上看,hierarchy是一个向量,向量内每个元素都是一个包含4个int型的数组。向量hierarchy内的元素和轮廓向量contours内的元素是一一对应的,向量的容量相同。hierarchy内每个元素的4个int型变量是hierarchy[i][0] ~ hierarchy[i][3],分别表示当前轮廓 i 的后一个轮廓、前一个轮廓、父轮廓和内嵌轮廓的编号索引。如果当前轮廓没有对应的后一个轮廓、前一个轮廓、父轮廓和内嵌轮廓,则相应的hierarchy[i][*]被置为-1。

 

参数4:定义轮廓的检索模式,取值如下:

CV_RETR_EXTERNAL:只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略;

CV_RETR_LIST:检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,所以hierarchy向量内所有元素的第3、第4个分量都会被置为-1,具体下文会讲到;

CV_RETR_CCOMP: 检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层;

CV_RETR_TREE: 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。

 

参数5:定义轮廓的近似方法,取值如下:

CV_CHAIN_APPROX_NONE:保存物体边界上所有连续的轮廓点到contours向量内;

CV_CHAIN_APPROX_SIMPLE:仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留;

CV_CHAIN_APPROX_TC89_L1:使用teh-Chinl chain 近似算法;

CV_CHAIN_APPROX_TC89_KCOS:使用teh-Chinl chain 近似算法。

 

参数6:Point偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,并且Point还可以是负值!





 





免责声明:本文仅代表作者个人观点,与华纳网无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。