我清理了给定的图像并使用以下内容作为输入:
输入图片
执行阈值并找到轮廓:
th = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(th , cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
现在是有趣的部分!
- 对于每个轮廓,找到极值点。这些是轮廓的top-most、bottom-most、right-most和left-most点.
- 比较一个轮廓的每个极值点与每个其他轮廓的距离
- 在欧几里得距离最小的点之间画一条线。
代码:
for i in range(len(cnts)):
min_dist = max(img.shape[0], img.shape[1])
cl = []
ci = cnts[i]
ci_left = tuple(ci[ci[:, :, 0].argmin()][0])
ci_right = tuple(ci[ci[:, :, 0].argmax()][0])
ci_top = tuple(ci[ci[:, :, 1].argmin()][0])
ci_bottom = tuple(ci[ci[:, :, 1].argmax()][0])
ci_list = [ci_bottom, ci_left, ci_right, ci_top]
for j in range(i + 1, len(cnts)):
cj = cnts[j]
cj_left = tuple(cj[cj[:, :, 0].argmin()][0])
cj_right = tuple(cj[cj[:, :, 0].argmax()][0])
cj_top = tuple(cj[cj[:, :, 1].argmin()][0])
cj_bottom = tuple(cj[cj[:, :, 1].argmax()][0])
cj_list = [cj_bottom, cj_left, cj_right, cj_top]
for pt1 in ci_list:
for pt2 in cj_list:
dist = int(np.linalg.norm(np.array(pt1) - np.array(pt2))) #dist = sqrt( (x2 - x1)**2 + (y2 - y1)**2 )
if dist < min_dist:
min_dist = dist
cl = []
cl.append([pt1, pt2, min_dist])
if len(cl) > 0:
cv2.line(img1, cl[0][0], cl[0][1], (255, 255, 255), thickness = 5)
输出图像: