《(penCV+Python)轮廓特征初阶与中阶.docx》由会员分享,可在线阅读,更多相关《(penCV+Python)轮廓特征初阶与中阶.docx(12页珍藏版)》请在优知文库上搜索。
1、图像的矩图像识别的一个核心问题是图像的特征提取,简单描述即为用一组简单的数据(数据描述量)来描述整个图像,这组数据越简单越有代表性越好。良好的特征不受光线、噪点、几何形变的干扰,图像识别技术的发展中,不断有新的描述图像特征提出,而图像不变矩就是其中一个。从图像中计算出来的矩通常描述了图像不同种类的几何特征如:大小、灰度、方向、形状等,图像矩广泛应用于模式识别、目标分类、目标识别与防伪估计、图像编码与重构等领域。严格来讲矩是概率与统计中的一个概念,是随机变量的一种数字特征。设XX为随机变量,C为常数,则量E(x-c)八k称为X关于C点的k阶矩。比较重要的两种情况如下:c=0,这时a_k=E(XA
2、k)称为X的k阶原点矩。c=E(X),这时g_k=E(XEX)八k称为X的k阶中心矩。一阶原点矩就是期望,一阶中心矩,l=0,二阶中心矩p_2就是X的方差Var(X)。在统计学上,高于4阶的矩极少使出,j可以去衡量分布是否有偏,,4可以衡量分布(密度)在均值附近的陡峭程度。针对一幅图像,我们把像素的坐标看成是一个二维随机变量(X,Y),那么一副灰度图可以用二维灰度图密度函数来表示,因此可以用矩来描述灰度图像的特征。OpenCV中提供的API用来计算中心矩和Hu矩,下面主要介绍Hu的原理。一幅MXN的数字图像f(i,j),其p+q阶几何矩m_pq和中心矩-pq为:MNmpq=EfiPfIfg)I
3、ljlMNMW=NEf)P(f-i)qf(ij)IJ1i=moo,1=m0m00其中f(i,j)为图像在坐标点(i,j)处的灰度值。若将m_00看做图像的灰度质量,贝加一丁)为图像的质心坐标,那么中心矩,pq反应的是图像灰度相对于其灰度质心的分布情况,可以用几何矩来表示中心矩03阶中心矩与几何矩的关系如下:00=ff1v1(i-i)0(j-j)(ij)=TnOoRO=3(TU加拉J)=O01=3f1(i-i)0(j-j)lf(ij)=0ll=fl0)1(jj)l(ij)=m”m1020=f1:1(i-i)2(j-j)of(ij)=m2Q-yn0i02=ETIE夕i(-f)(J3)2(iJ)=1
4、12Omol30=ETI:1(i-i)3(j-j)o(ij)=rn30-2xm2o2i2m10M12ff17l(i-i)l(j-jm,J)n12-2mllZTno2+22m1021=f1(i-i)2(j-j)1f(ij)=m2-2xmn-ym202x2m01O3=17(-W-J)3(iJ)m03-2yn02+2y2m0l为了消除图像比例变化带来的影响,定义规格化中心矩如下:Vpq=(7=,P+)=2,3,)利用二阶和三阶规格中心矩可以导出下面7个不变矩组(17),它们在图像平移、旋转和比例变化时保持不变:O+知2小2=()2+4垂3=(Tho_3-12)23(%-)2小4=(仍O+?12)2+
5、(%1+)2中5=(+3)()(%o+)2-3(+)2(3奥I-)(7fe+)3(+712)2(7fo+)2小=()(+12(出)2j+4九(小O+12)(TfeI+)小7=(3仍1)(+)(+*712)23(物+)2i(3%2m0)(仍1+)3(+12)2(仍1+)2OpenCV中提供了cv2.moments。来计算图像中的中心矩(最高到三阶)。同时配合函数ContourArea函数计算轮廓面积和arcLength来计算轮廓或曲线长度。我们来看函数原型:cv2.moments(InputArrayarray,boolbinaryimage=false)array:输入数组,可以是光栅图像(单
6、通道,8-bit或浮点型二维数组),或者是一个二维数组,二维数组类型为Point或Point2fobinaryimage:默认值是false,如果为true,则所有非零的像素都会按值1对待,也就是说相当于对图像进行了二值化处理,阈值为1,此参数仅对图像有效。来看代码:importcv2importnumpyasnpimg=cv2.imread(pie.png)gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)contour=cv2.findContours(gray,cv2.RETR_TREE,cv2.CHAIN_APPROX_S!MPLE)|0cv2.draw
7、Contours(img,contour,-1,(0,0,255),2)cv2.imshow(,res,img)cnt=contour0M=cv2.moments(cnt)print(M)cv2.waitKey(0)cv2.destroyA11Windows()这是我们得到的结果:D:Anaconda3envspytorchpytho.exeD:/合集/代习/代码绻习/Iabviear.py,m8,:55865.,al:1447499.,*al*:12962615.5,*三2*:417898496.S,三11,:355761Processfinishedwithexitcode8这是我们得出的
8、所有的矩,现在我们对代码进行改进,计算出对象的重心(质心):_MlO_磔Oi以一LF一两,代码:importcv2importnumpyasnpimg=cv2.imread(,pie.pngu)gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)contour=cv2.findContours(gray,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)0cv2.drawContours(img,contour,-1,(0,0,255),2)cv2.imshow(,res,img)cnt=contour0M=cv2.moments(cnt
9、)cx=int(Mml0M,m00J)cy=int(Ml,m0Mm00l)print(cx,cy)cv2.waitKey(0)cv2.destroyAHWindows()D:Anaconda3evsptorchpython.ee0:/2震/代码练习/代码播习八abview.py259232Processfinishedwithexitcode可以得出重心坐标。轮廓的面积我们可以使用OPenCV中的函数:cv2.contourArea(InputArraycontour,booloriented=false)contour:是一个向富,二维点。oriented:有默认值false,面向区域标识符
10、,如果为true,该函数返回一个带符号的面积,其正负取决于轮廓的方向(顺时针还是逆时针)。根据这个特性可以根据面积的符号来确定轮廓的位置。如果是默认值false,则面积以绝对值的形式返回。我们来看代码:importcv2importnumpyasnpimg=cv2.imread(,pie.png)gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)contour=cv2.findContours(gray,cv2.RETR_TREE,cv2.CHAIN_APPROX_SlMPLE)lOcv2.drawContours(img,contour,-1,(0,0,255
11、),2)cv2.imshow(,res,img)cnt=contour0M=cv2.moments(cnt)area=cv2.contourArea(cnt)print(area)cv2.waitKey(0)cv2.destroyAllWindows()可以看到输出的面积:D:Anaconda3envspytorchpython.ee0:/合拿/代码箍习/代码博习八abvien.py55865.Processfinishedwithexitcode事实上,我们也可以使用刚刚讲述的图像的矩来完成,图像的面积等于它的0阶矩:Mrmooimportcv2importnumpyasnpimg=cv2.
12、imread(,pie.png)gray=cv2.cvtColor(img,cv2.COLOR-BGR2GRAY)contour=cv2.findContours(gray,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)lOcv2.drawContours(img,contour,-1,(0,0,255),2)cv2.imshow(,res,img)cnt=contour0M=cv2.moments(cnt)area=int(M,m00)print(area)cv2.waitKey(0)cv2.destroyAllWindows()D:Anaconda3envsp
13、ytorchpython.exe0:/合集/代码练习/代码练习labvie.py55865Processfinishedwithexitcode可以看到,效果是一样的。轮廓的周长函数原型:retval=cv.arcLength(curve,closed)第一个参数指代的是输入的二维点的向量。第二个参数代表曲线是否闭合。来看代码:importcv2importnumpyasnpimg=cv2.imread(,pie.pngu)gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)contour=cv2.findContours(gray,cv2.RETR_TREE,c
14、v2.CHAIN_APPROX_S!MPLE)lOcv2.drawContours(img,contour,-1,(0,0,255),2)cv2.imshow(,res,img)cnt=contour0C=cv2.arcLength(cnt,True)pnt(C)cv2.waitKey(0)cv2.destroyAllWindows()可以直接计算轮廓的周长。OpenCV+Python)轮廓特征中阶本次我们将讨论OPenCV中图像轮廓的另一些特征,它们将非常有用。边界矩形有两类边界矩形。A直边界矩形一个直矩形(就是没有旋转的矩形)。它不会考虑对象是否旋转。所以边界矩形的面积不是最小的。可以使用函数cv2.boundingRect()查找得到,我们来看函数原型:x,y,w,h=cv2.boundingRect(cnt)(x,y)为矩形左上角的坐标;(w,h)是矩形的宽和高,通常情况下,ent代表识别的轮廓。之后我们利用cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)画出矩形。参数解释:第一个参数:img是原图。第二个参数:(x,y)是矩阵的左上点坐标。第三个参数:(x+w,y+h)是矩阵的右下点坐标。第四个参数:(0,255,0)是画线对应的rgb颜色。第五个参数:2是所画的线的宽度。我们来看代码:importcv2# 读取图片