opencv18:轮廓属性

目标

在这里,将学习提取一些常用的物体属性

  • 坚实度(image solidity)
  • 等效直径(Equivalent Diameter)
  • 掩模图像(mask)
  • 平均强度(Mean Intensity)

长宽比( Aspect Ratio)

长宽比是对象边界矩形的宽度与高度的比值

A s p e c t    R a t i o = W i d t h H e i g h t Aspect \;Ratio=\frac{Width}{Height} AspectRatio=HeightWidth

#长宽比 
import cv2
import numpy as np
img = cv2.imread('approx.png', 0)
rows, cols = img.shape
ret, thresh = cv2.threshold(img, 127, 250, 0)
cnts, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
x, y, w, h = cv2.boundingRect(cnts[0])
aspect_ratio = float(w)/h  # 1.09

范围(Extent)

范围是轮廓区域与边界矩形区域的比值

E x t e n t = O b j e c t    A r e a B o u n d i n g    R e c t a n g l e    A r e a Extent=\frac{Object \;Area}{Bounding \;Rectangle \;Area} Extent=BoundingRectangleAreaObjectArea

area = cv2.contourArea(cnts[0])
x, y, w, h = cv2.boundingRect(cnts[0])
rect_area = w * h
extent = float(area)/rect_area   # 0.298

坚实度(Solidity)

坚实度是等高线面积与其凸包面积之比

S o l i d i t y = C o n t o u r    A r e a C o n v e x    H u l l    A r e a Solidity=\frac{Contour\;Area}{Convex\;Hull\;Area} Solidity=ConvexHullAreaContourArea

# 坚实度
area = cv2.contourArea(cnts[0])
hull = cv2.convexHull(cnts[0])
hull_area = cv2.contourArea(hull)
solidity = float(area)/hull_area  # 0.82

等效直径(Equivalent Diameter)

等效直径是面积与轮廓面积相同的圆的直径

E q u i v a l e n t    D i a m e t e r = 4 × C o n t o u r    A r e a π Equivalent \; Diameter=\sqrt\frac{4 \times Contour \;Area}{\pi} EquivalentDiameter=π4×ContourArea

area = cv2.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi)  # 97.3  area = pi*(d/2)^2

取向

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

(x,y),(MA,ma),angle = cv2.fitEllipse(cnts[0])  
# 167.77357482910156, 166.88461303710938, 60.207035064697266, 210.24307250976562, 136.4932098388672

掩码和像素点

在某些情况下,可能需要构成该对象的所有点。可以按照以下步骤完成:

mask = np.zeros(imgray.shape,np.uint8)
cv2.drawContours(mask,[cnts[0]], 0, 255, -1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv2.findNonZero(mask)
'''
array([[108, 158],
       [108, 159],
       [108, 160],
       ...,
       [258, 255],
       [258, 256],
       [258, 257]], dtype=int64), lenth=7664
'''

这里提供了两个方法,

  • 使用Numpy函数
  • 使用OpenCV函数(最后的注释行)。
    结果也是一样的,只是略有不同。Numpy给出的坐标是(行、列)格式,而OpenCV给出的坐标是(x,y)格式。所以基本上答案是可以互换的。注意,row = x, column = y

最大值,最小值及其位置

可以使用掩码图像找到这些参数

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(img, mask=mask)
# (128.0, 255.0, (138, 116), (158, 108))

平均颜色或平均强度

使用掩码可以找到对象的平均颜色,或者可以是灰度模式下物体的平均强度

mean_val = cv2.mean(img, mask = mask)
# (251.65057411273483, 0.0, 0.0, 0.0), 各个通道的均值

极端点

极点是指对象的最顶部,最底部,最右侧和最左侧的点

leftmost = tuple(cnts[0][cnts[0][:,:,0].argmin()][0])
rightmost = tuple(cnts[0][cnts[0][:,:,0].argmax()][0])
topmost = tuple(cnts[0][cnts[0][:,:,1].argmin()][0])
bottommost = tuple(cnts[0][cnts[0][:,:,1].argmax()][0])
# ((94, 137), (258, 257), (158, 108), (254, 258))

cv2.circle(img, leftmost, 5, (255,0,0))
cv2.circle(img, rightmost, 5, (255,0,0))
cv2.circle(img, topmost, 5, (255,0,0))
cv2.circle(img, bottommost, 5, (255,0, 0))
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
可以看到最右点与最下点比较重合

附加资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncle_ll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值