更新:我自己计算的距离与
cv2
返回的距离之间的比率似乎正好是 256。这并不奇怪,因为查看他们的代码(第 394 行here)显示像素距离成倍增加到 256。我想我只是不明白为什么。
我正在使用
cv2.convexityDefects
来查找某些形状的凸缺陷。我希望计算缺陷的深度(到凸包的距离,这里解释得很好)。
但是,我得到的距离太大了,没有意义。我还尝试使用 cv2.convexityDefects 的起点和终点输出参数手动计算距离(参见下面的代码),并获得更合理的结果。
cv2.convexityDefects
计算出的距离为,
>> d
array([21315, 26578, 19093, 56472, 35230, 20476, 26825], dtype=int32)
这在大约 500 像素宽的图像上下文中完全没有意义。我做错了什么?
更多信息:
这是我为本次测试创建的图像(呃,我的意思是艺术品),
这是代码:
from numpy.linalg import norm
# Load an image
img = cv2.imread('buff.png')
# Threshold
ret, img = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
# Detect edges
edges = cv2.Canny(img, 1, 2)
# Find contours
cnts, h = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# Find convex hull
hull = cv2.convexHull(cnts[0], returnPoints = False)
# Find defects
defects = cv2.convexityDefects(cnts[0], np.sort(np.squeeze(hull)))
# Reshape the output
s = np.reshape(defects,(-1,4))[:,0] # start point idx
e = np.reshape(defects,(-1,4))[:,1] # end point idx
f = np.reshape(defects,(-1,4))[:,2] # defect idx
d = np.reshape(defects,(-1,4))[:,3] # distances as calculated by cv2.convexityDefects
# Draw contours in red, convex hull in blue
img = cv2.drawContours(img, cnts[0], -1, (255,0,0), 2)
img = cv2.polylines(img, [cnts[0][np.squeeze(hull)]], True, (0,0,255), 3)
# Calculate distances manually and put in a list d2
d2 = list()
for i in range(len(f)):
# Draw the defects in blue, start points in pink:
img = cv2.circle(img, tuple(cnts[0][f[i]][0]), 5,(0, 0, 255), -1)
img = cv2.circle(img, tuple(cnts[0][s[i]][0]), 5,(255, 0, 255), -1)
# Manually calculate the distances as the distances between the defects (blue points)
# and the line defined between each pair of start and end points (pink here, for demonstration)
d2.append(norm(np.cross(cnts[0][s[i]][0]-cnts[0][e[i]][0], cnts[0][e[i]][0]-cnts[0][f[i]][0]))/norm(cnts[0][s[i]][0]-cnts[0][e[i]][0]))
pp.imshow(img)
pp.show()
这是上述代码应用于测试图像时的输出:
这是故意的。
fixpt_depth is fixed-point approximation (with 8 fractional bits) of the distance between the farthest contour point and the hull. That is, to get the floating-point value of the depth will be fixpt_depth/256.0.