opencv 中 那些 常用的轮廓属性和函数

在这里,我们将学习提取一些常用的属性,如固体,等效直径,掩模图像,平均强度等。更多功能可以在Matlab的区域道具文档中找到。

1. Aspect Ratio(纵横比)

它是对象的边界矩形的宽度与高度的比率。

x,y,w,h = cv.boundingRect(cnt)
aspect_ratio = float(w)/h

2. Extent

Extent范围是指轮廓面积与边界矩形面积之比。

area = cv.contourArea(cnt)
x,y,w,h = cv.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area

3. Solidity

Solidity度是轮廓面积与凸包面积之比。

area = cv.contourArea(cnt)
hull = cv.convexHull(cnt)
hull_area = cv.contourArea(hull)
solidity = float(area)/hull_area

4. Equivalent Diameter

Equivalent Diameter是面积与轮廓面积相同的圆的直径。

area = cv.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi)

5. Orientation

方向是物体指向的角度。下面的方法也给出了主轴和副轴的长度。

(x,y),(MA,ma),angle = cv.fitEllipse(cnt)

6. Mask and Pixel Points

在某些情况下,我们可能需要包含该对象的所有点。可以这样做:

mask = np.zeros(imgray.shape,np.uint8)
cv.drawContours(mask,[cnt],0,255,-1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv.findNonZero(mask)

这里给出了两个方法,一个使用Numpy函数,另一个使用OpenCV函数(最后的注释行)来完成相同的操作。结果也一样,只是略有不同。Numpy以**(行,列)**格式给出坐标,OpenCV以**(x,y)**格式给出坐标。所以基本上答案会互换。注意,行= x,列= y。

7. Maximum Value, Minimum Value and their locations

我们可以使用遮罩图像找到这些参数。

min_val, max_val, min_loc, max_loc = cv.minMaxLoc(imgray,mask = mask)

8. Mean Color or Mean Intensity

在这里,我们可以找到一个物体的平均颜色。或者它可以是物体在灰度模式下的平均强度。我们再次使用相同的蒙版来做这件事。

mean_val = cv.mean(im,mask = mask)

9. Extreme Points

极值点是指物体的最上、最下、最右和最左的点。

leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])

例如,如果我应用它到一个印度地图,我得到以下结果:

 

10.Convexity Defects(凸包缺陷)

我们在关于轮廓的先前文章中了解了什么是凸包。凸包和本体的任何偏差都可以认为是凹凸缺陷。
OpenCV提供了一个现成的函数来查找这个问题,即c . convexitydefects()。一个基本的函数调用如下所示:

hull = cv.convexHull(cnt,returnPoints = False)
defects = cv.convexityDefects(cnt,hull)

记住,我们必须通过returnPoints = False来寻找凸包,以找到凸性缺陷。
它返回一个数组,其中每一行包含这些值-[起始点,结束点,最远点,到最远点的近似距离]。我们可以用图像来表示它。我们画一条连接起点和终点的线,然后在最远处画一个圆。记住,返回的前三个值是cnt的索引。所以我们必须从cnt中获取这些值。

import cv2 as cv
import numpy as np
img = cv.imread('star.jpg')
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,thresh = cv.threshold(img_gray, 127, 255,0)
contours,hierarchy = cv.findContours(thresh,2,1)
cnt = contours[0]
hull = cv.convexHull(cnt,returnPoints = False)
defects = cv.convexityDefects(cnt,hull)
for i in range(defects.shape[0]):
    s,e,f,d = defects[i,0]
    start = tuple(cnt[s][0])
    end = tuple(cnt[e][0])
    far = tuple(cnt[f][0])
    cv.line(img,start,end,[0,255,0],2)
    cv.circle(img,far,5,[0,0,255],-1)
cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()

And see the result:

11.Point Polygon Test

此函数查找图像中点与轮廓线之间的最短距离。当点在轮廓线外时,返回的距离为负,点在轮廓线内时返回的距离为正,点在轮廓线上返回的距离为零。

例如,我们可以检查点(50,50)如下:

dist = cv.pointPolygonTest(cnt,(50,50),True)

pointPolygonTest()

double cv::pointPolygonTest(InputArray contour,
  Point2f pt,
  bool measureDist 
 )  
Python:
 retval=cv.pointPolygonTest(contour, pt, measureDist)

该函数确定点是在轮廓线内、外还是在边缘上(或与顶点重合)。相应地,它返回正(内部)、负(外部)或零(沿边)值。当measureDist=false时,返回值分别为+1、-1和0。否则,返回值为该点与最近的轮廓边之间的有符号距离。 

参数:

contour输入轮廓
pt点测试轮廓
measureDist如果为真,函数估计从该点到最近轮廓边的带符号距离。否则,函数只检查点是否在轮廓线内。

12.Match Shapes

OpenCV附带了一个函数cv.matchShapes(),它使我们能够比较两个形状或两个轮廓,并返回一个显示相似性的度量。结果越低,匹配越好。它是基于hu矩值计算的。不同的测量方法在文档中有说明。

import cv2 as cv
import numpy as np
img1 = cv.imread('star.jpg',0)
img2 = cv.imread('star2.jpg',0)
ret, thresh = cv.threshold(img1, 127, 255,0)
ret, thresh2 = cv.threshold(img2, 127, 255,0)
contours,hierarchy = cv.findContours(thresh,2,1)
cnt1 = contours[0]
contours,hierarchy = cv.findContours(thresh2,2,1)
cnt2 = contours[0]
ret = cv.matchShapes(cnt1,cnt2,1,0.0)
print( ret )

我试着用下面给出的不同形状匹配形状:

  • Matching Image A with itself = 0.0
  • Matching Image A with Image B = 0.001946
  • Matching Image A with Image C = 0.326911
  • 看,即使是图像旋转也不会对这种比较产生太大影响。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值