opencv教程(基于python)----图象轮廓(一)

xiaoxiao2021-02-28  9

轮廓可以简单的看做连续的点(包括边界)连成的曲线,他们具有相同的颜色或者灰度。主要应用在形状分析和物体的检测与识别。

处识轮廓

一般来说为了更加准确,要使用二值化图象,在寻找轮廓之前,进行阈值化处理或者Canny边缘检测;查找轮廓的函数会更改原始图象,如果后期还想使用原始图像的话最好找另一个变量储存;一般物体是白色而背景是黑色。 这里哟两个函数cv2.findContours()和cv2.drawContours()分别是查找轮廓和绘制轮廓的函数。下面具体看一下吧。

cv2.indContours(image, mode, method, contours=None, hierarchy=None, offset=None)

image输入图像。 mode是检索方式,cv2.RETR_EXTERNAL表示只检测外轮廓,cv2.RETR_LIST检测的轮廓不建立等级关系, cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层,v2.RETR_TREE建立一个等级树结构的轮廓。 method是轮廓近似方法 cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1;cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息;cv2.CHAIN_APPROX_TC89_L1 CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法。 在说以下函数的返回内容:第一个是图象,其实与原图像没什么区别;第二个是轮廓(轮廓的坐标),不同图像的轮廓数量可能不同;第三个是轮廓的层析结构,是一个矩阵详细。

cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)

函数的第一个参数是输入的原始图像;第二个参数是轮廓(一般是第一个函数求出来的);第三个参数是轮廓的索引(如果为-1的话,绘制所有的轮廓);第四个是轮廓的颜色;最后一个是轮廓的粗细。

import cv2 import numpy as np import matplotlib.pyplot as plt img=cv2.imread('C:/Users/dell/Desktop/u12.jpg') imgray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret,thresh=cv2.threshold(imgray,127,255,0) image,coutours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) im=cv2.drawContours(img,coutours,-1,(255,0,0),3) cv2.imshow('image',im) cv2.waitKey(0) cv2.destroyAllWindows()

可以说复杂边界的效果和阈值化有很大关系。可以参考前面的手动调控阈值,这样绘制出来的边界就会有很大不同。但是对于这个简单图象,我就不演示了。

轮廓特征

这里我们关系轮廓的一些具体特征:面积,周长,重心边界框

图象的矩可以帮助计算面积,质心。 主要用到的函数是cv2.moments()

cv2.moments(array, binaryImage=None)

array是输入的矩阵,一般我们是用的输入的轮廓。

mport cv2 import numpy as np import matplotlib.pyplot as plt img=cv2.imread('C:/Users/dell/Desktop/u0.jpg') imgray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret,thresh=cv2.threshold(imgray,127,255,0) image,coutours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #第一个轮廓 cnt=coutours[0] m=cv2.moments(cnt) print(m) #输出结果 #{'m00': 2.0, 'm10': 498.66666666666663, 'm01': 720.6666666666666, 'm20': 124334.66666666666, 'm11': 179686.0, 'm02': 259680.66666666666, 'm30': 31000998.400000002, 'm21': 44801814.13333333, 'm12': 64746886.13333333, 'm03': 93571920.4, 'mu20': 0.44444444445252884, 'mu11': -0.22222222218988463, 'mu02': 0.44444444446708076, 'mu30': -0.11851851642131805, 'mu21': 0.05925924895080925, 'mu12': 0.05925924373636349, 'mu03': -0.11851851642131805, 'nu20': 0.11111111111313221, 'nu11': -0.05555555554747116, 'nu02': 0.11111111111677019, 'nu30': -0.020951311664420796, 'nu21': 0.010475654195284756, 'nu12': 0.010475653273492267, 'nu03': -0.020951311664420796}

输出结果,我看的中文文档没有很好的解释,等我日后补充吧。但是可以根据输出的结果来计算一些东西。比如x轴的中心为M[‘m10’]/M[‘m00’],y轴的中心是M[‘m01’]/M[‘m00’]

轮廓面积/周长

轮廓面积可以是上面的M[‘m00’],也可以是函数cv2.contourArea()

cv2.contourArea(contour, oriented=None)

contour是轮廓。

area=cv2.contourArea(cnt) #结果是2

轮廓的周长这个函数是cv2.arcLength()

cv2.arcLength(curve, closed)

第一个参数是轮廓;第二个参数是图象是否闭合,填True或者False。

length=cv2.arcLength(cnt,True) #输出结果:6.828427076339722

好了今天就先到这了。

转载请注明原文地址: https://www.6miu.com/read-1900300.html

最新回复(0)