2015-06-08 32 views
9

Potrzebuję uzyskać listę współrzędnych x i y współrzędnych pikseli, które moduł dopasowujący wybiera w dostarczonym kodzie. Używam Python i OpenCV. Czy ktoś może mi pomóc?Jak uzyskać współrzędne pikseli z dopasowywania elementów w OpenCV Python

img1=cv2.imread('DSC_0216.jpg',0) 
img2=cv2.imread('DSC_0217.jpg',0) 

orb=cv2.ORB(nfeatures=100000) 
kp1,des1=orb.detectAndCompute(img1,None) 
kp2,des2=orb.detectAndCompute(img2,None) 

img1kp=cv2.drawKeypoints(img1,kp1,color=(0,255,0),flags=0) 
img2kp=cv2.drawKeypoints(img2,kp2,color=(0,255,0),flags=0) 
cv2.imwrite('m_img1.jpg',img1kp) 
cv2.imwrite('m_img2.jpg',img2kp) 

bf=cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) 
matches=bf.match(des1,des2) 
matches=sorted(matches, key= lambda x:x.distance) 

Odpowiedz

13

Wiemy, że keypoints są przechowywane w kp1 i kp2 gdzie są funkcje pasuje do pierwszego i drugiego obrazu odpowiednio. W perspektywie cv2.ORB są to macierze 2D, gdzie każdy wiersz jest punktem kluczowym, który jest wykrywany na pierwszym obrazie, kp1, a drugi obraz, kp2.

W twoim przypadku, ponieważ używasz cv2.BFMatch, matches zwraca listę cv2.DMatch obiektów, gdzie każdy obiekt zawiera kilka elementów .... Wśród nich są dwie ważne członkowie:

  • queryIdx - indeks lub rząd matrycy kp1 procentowej punkt, który odpowiada
  • trainIdx - indeksem rzędu matrycy punktowej kp2 procentowej odpowiada

Dlatego queryIdx i trainIdx powiedzieć, które ORB wyposażony mecz pomiędzy kp1 i kp2. W związku z tym można ich użyć do indeksowania w kp1 i kp2 i uzyskania członu pt, który jest krotką współrzędnych (x,y), które określają rzeczywiste współrzędne przestrzenne dopasowań.

Wszystko co musisz zrobić, to iterację każdego obiektu cv2.DMatch w matches, dołącz do listy współrzędnych zarówno kp1 i kp2 i gotowe.

coś takiego:

# Initialize lists 
list_kp1 = [] 
list_kp2 = [] 

# For each match... 
for mat in matches: 

    # Get the matching keypoints for each of the images 
    img1_idx = mat.queryIdx 
    img2_idx = mat.trainIdx 

    # x - columns 
    # y - rows 
    # Get the coordinates 
    (x1,y1) = kp1[img1_idx].pt 
    (x2,y2) = kp2[img2_idx].pt 

    # Append to each list 
    list_kp1.append((x1, y1)) 
    list_kp2.append((x2, y2)) 

Zauważ, że mogłem tylko zrobić list_kp1.append(kp1[img1_idx].pt) i taka sama dla list_kp2, ale chciałem, aby to bardzo jasne, w jaki sposób interpretować współrzędne przestrzenne. Można też pójść o krok dalej i zrobić listowych:

list_kp1 = [kp1[mat.queryIdx].pt for mat in matches] 
list_kp2 = [kp2[mat.trainIdx].pt for mat in matches] 

list_kp1 będzie zawierać współrzędne przestrzenne punktu fabularnego, który pasował do analogicznego stanowiska w list_kp2. Innymi słowy, element i z list_kp1 zawiera przestrzenne współrzędne punktu cechy z img1, które są dopasowane do odpowiedniego punktu cechy od img2 w list_kp2, którego współrzędne przestrzenne są w elemencie i.


W niewielkim marginesie, użyłem tego pojęcia kiedy pisałem obejście dla drawMatches bo OpenCV 2.4.x, owijka Pythona do funkcji C++ nie istnieje, więc skorzystał z powyższej koncepcji w lokalizowanie współrzędnych przestrzennych pasujących funkcji między dwoma obrazami w celu napisania mojej własnej implementacji.

Sprawdź to, jeśli chcesz!

module' object has no attribute 'drawMatches' opencv python

+3

Niż tak bardzo! – kotopanda