1.特征矩

特征矩可以帮助计算一些特征,例如物体的质心,物体的面积等。函数cv.moments()会将计算得到的矩以一个字典的形式返回。

import cv2 as cv

img=cv.imread('./images/lena.jpeg',0)
ret,thresh=cv.threshold(img,127,255,0)
contours,hierarchy=cv.findContours(img,1,2)
cnt=contours[0]
M=cv.moments(cnt)
print(contours)
print(cnt)
print(M)

根据这些矩值,可以计算出对象的重心:

cx=int(M['m10']/M['m00'])
cy=int(M['m01']/M['m00'])
print(cx,cy)

2.轮廓面积

可以使用cv.contourArea()计算得到,也可以使用矩(0阶矩),M['m00']

area=cv.contourArea(cnt)
print(area)

3.轮廓周长

也称为弧长。可以使用cv.arcLength()函数找到它。第二个参数指定形状是闭合轮廓(True)还是曲线。

perimeter=cv.arcLength(cnt,True)
print(perimeter)

4.轮廓近似

根据指定的精度,可以将轮廓形状近似为顶点数量较少的其他形状。它是DOuglas-Peucker算法的实现。

在图像中找到一个正方形,但是由于图像中的某些问题,没有得到一个完美的正方形,而是一个坏形状(如下图所示)。现在,可以使用此功能来近似形状。第二个参数称为epsilon,它是从轮廓到近似轮廓的最大距离。它是应精度参数。需要正确选择epsilon才能获得正确的输出。

epsilon = 0.1*cv.arcLength(cnt,True)
approx = cv.approxPolyDP(cnt,epsilon,True)

下面图像中,在第二张图片中,绿线显示了epsilon=弧长的10%时的近似曲线。第三幅图显示了等于弧长度的1%时的情况。第三个参数指定曲线是否闭合。

 5.轮廓凸包

凸包外观看起来与轮廓逼近相似,但不相似(在某些情况下两者可能提供相同的结果)在这里,cv.convexHull()函数检测曲线是否存在凸凹缺陷并对其进行校正。一般而言,凸曲线是始终凸出或至少平坦的曲线。如果在内部凸出,则称为凸度缺陷。例如,检查下面的受的图像。红线显示手的凸包。双向箭头标记显示凸度缺陷。这是凸包与轮廓线之间的局部最大偏差。

 

hull=cv.convexHull(points,hull,clockwise,returnPoints)

参数:

  • points:要传入的轮廓
  • hull:输出,通常不需要
  • clockwise:方向标志,如果设置为True,输出的凸包是顺时针方向的,否则为逆时针方向。
  • returnPoints:默认值为True。它会返回凸包上点的坐标,如果设置为False,就会返回与凸包点对应的轮廓上的点。
hull = cv.convexHull(cnt)

但是如果想要获得凸性缺陷,需要把returnPoints设置为False。以上面矩形为例,首先找到它的轮廓为cnt。现在把returnPoints设置为True查找凸包,得到的就是矩形的四个角点。把returnPoints设置为False,得到的是轮廓点的索引。

6.检查凸度

cv.isContourConvex()具有检查曲线是否凸出的功能。它只是返回True还是False。

k=cv.isContourConvex(cnt)

7.边界矩形

有两种类型的边界矩形

a.直角矩形

它是一个矩形,不考虑物体的旋转。所以边界矩形的面积不是最小的。它是由函数cv.boundingRect()找到的。

令(x,y)为矩形的左上角坐标,而(w,h)为矩形的宽度和高度

x,y,w,h = cv.boundingRect(cnt)
cv.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

b.旋转矩形

边界矩形是用最小面积绘制的,所以它也考虑了旋转。使用的函数是cv.minAreaRect()。它返回一个Box2D结构,其中包含以下细节(中心(x,y),(宽度,高度),旋转角度)。但要画出这个矩形,需要矩形的四个角。它由函数cv.boxPoints()获得。

rect = cv.minAreaRect(cnt)
box = cv.boxPoints(rect)
box = np.int0(box)
cv.drawContours(img,[box],0,(0,0,255),2)

两个矩形都显示在一张单独的图像中。绿色矩形显示正常的边界矩形。红色矩形是旋转后的矩形。

 8.最小闭合圈

使用函数cv.minEnclosingCircle()查找对象的圆周。它是一个以最小面积完全覆盖物体的圆。

(x,y),radius = cv.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
cv.circle(img,center,radius,(0,255,0),2)

9. 拟合一个椭圆

把一个椭圆拟合到一个物体上。它返回内接椭圆的旋转矩形。

ellipse = cv.fitEllipse(cnt)
cv.ellipse(img,ellipse,(0,255,0),2)

 10.拟合一条直线

可以将一条直线拟合到一组点。

rows,cols = img.shape[:2]
[vx,vy,x,y] = cv.fitLine(cnt, cv.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
cv.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)

 

 posted on 2024-05-04 17:42  会飞的金鱼  阅读(23)  评论(0)    收藏  举报