import cv2
import numpy as np
# read in OP's example image, making sure we ignore the red arrow
img = cv2.imread('jGssp.png')[:, :, 1]
_, img = cv2.threshold(img, 127, 255, 0)
# get the contour of the shape
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contour = contours[0][:, 0, :]
# add the first point as the last, to close it
contour = np.concatenate((contour, contour[0, None, :]))
# compute centroid
def cross_product(v1, v2):
"""2D cross product."""
return v1[0] * v2[1] - v1[1] * v2[0]
sum = 0.0
xsum = 0.0
ysum = 0.0
for ii in range(1, contour.shape[0]):
v = cross_product(contour[ii - 1, :], contour[ii, :])
sum += v
xsum += (contour[ii - 1, 0] + contour[ii, 0]) * v
ysum += (contour[ii - 1, 1] + contour[ii, 1]) * v
centroid = np.array([ xsum, ysum ]) / (3 * sum)
# Compute coefficient of variation of distances to centroid (==circularity)
d = np.sqrt(np.sum((contour - centroid) ** 2, axis=1))
circularity = np.std(d) / np.mean(d)
1条答案
按热度按时间zf2sa74q1#
“圆度”度量对周长的精确估计很敏感。
cv2.arcLength()
所做的是将多边形每条边的长度相加,这严重高估了轮廓的长度。我认为这是该度量对您不起作用的主要原因。使用更好的周长估计器,您会得到有用的结果。另一个可能更有用的度量是“圆度”,定义为半径的变异系数。简而言之,你计算每个多边形顶点(即轮廓点)到质心的距离,然后确定这些距离的变异系数(== std / mean)。
我编写了一个快速的Python脚本,从OpenCV轮廓开始计算: