[英]How to find nearest points between two contours in OpenCV
使用雙for
循環可能很耗時。 根據 Giovanni Tardini 的評論和CodeReview.stackexchange 的回答,您可以迭代單個輪廓的點。 我沒有做過速度比較,但是原作者聲稱矢量化可以加快計算速度。
代碼:
# To draw the final result
img = cv2.imread('image_path', 1)
# grayscale to binary conversion -> find contours
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
th = cv2.threshold(gray,127,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
contours, hierarchy = cv2.findContours(th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# store the 2 contours
c1, c2 = contours[0], contours[1]
# Function to index and distance of the point closest to an array of points
# borrowed shamelessly from: https://codereview.stackexchange.com/questions/28207/finding-the-closest-point-to-a-list-of-points
def closest_point(point, array):
diff = array - point
distance = np.einsum('ij,ij->i', diff, diff)
return np.argmin(distance), distance
# initialize some variables
min_dist = np.max(th.shape)
chosen_point_c2 = None
chosen_point_c1 = None
# iterate through each point in contour c1
for point in c1:
t = point[0][0], point[0][1]
index, dist = closest_point(t, c2[:,0])
if dist[index] < min_dist :
min_dist = dist[index]
chosen_point_c2 = c2[index]
chosen_point_c1 = t
# draw the two points and save
cv2.circle(img,(chosen_point_c1), 4, (0,255,255), -1)
cv2.circle(img,tuple(chosen_point_c2[0]), 4, (0,255,255), -1)
cv2.imshow('Result', img)
結果:
(我使用了問題中共享的圖像。如果仔細觀察,您會在每個輪廓中看到一個黃點。)
此鏈接提供了其他解決方案,其中 KDtrees(由 Daniel F 提出)是一個選項。
由於問題中沒有測試數據而無法測試,但這應該會讓你繼續。 使用KDTree
s。
from scipy.spatial import KDTree
max_distance = 10 #tune to your data
kd_trees = [KDTree(c) for c in contours]
out = {}
for i, j in zip(np.triu_indices((len(contours),)*2, 1)):
coo = kd_trees[i].sparse_distance_matrix(kd_trees[j],
max_distance = max_distance,
output_type = 'coo_matrix')
ix = np.argmin(coo.data)
out[(i, j)] = [contours[i][coo.row[ix]], contours[j][coo.col[ix]]]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.