簡體   English   中英

如何在 OpenCV 中找到兩個輪廓之間的最近點

[英]How to find nearest points between two contours in OpenCV

對於兩個輪廓 c1 和 c2,如何找到輪廓之間最近的點。

一個解決方案可能是遍歷所有點,獲得歐幾里得距離和 go 最小歐幾里得距離,但這將具有巨大的時間復雜度。

我使用cv2.findContours來查找輪廓。

contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

在此處輸入圖像描述

我想找到兩個輪廓之間以藍色顯示的兩個點。

使用雙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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM