2015-06-08 24 views
9

Tôi cần có danh sách các tọa độ xy của pixel mà đối sánh đối sánh địa lý chọn trong mã được cung cấp. Tôi đang sử dụng Python và OpenCV. Ai giúp tôi với?Cách lấy tọa độ pixel từ Đối sánh tính năng trong Python OpenCV

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) 

Trả lời

13

Chúng ta biết rằng keypoint của bạn được lưu trữ trong kp1kp2 nơi họ là những tính năng phù hợp cho hình ảnh đầu tiên và thứ hai tương ứng. Trong phối cảnh cv2.ORB, đây là các ma trận 2D trong đó mỗi hàng là một điểm quan trọng được phát hiện trong hình ảnh đầu tiên, kp1 và hình ảnh thứ hai, kp2.

Trong trường hợp của bạn bởi vì bạn đang sử dụng cv2.BFMatch, matches trả về một danh sách các đối tượng cv2.DMatch nơi từng đối tượng chứa một số thành viên .... trong đó có hai thành viên quan trọng:

  • queryIdx - Chỉ số hoặc hàng của ma trận kp1 lãi suất thời điểm đó phù hợp với
  • trainIdx - chỉ số hoặc hàng của ma trận điểm kp2 lãi suất phù hợp với

Do đó, queryIdxtrainIdx cho bạn biết tính năng ORB nào khớp giữa kp1kp2. Do đó, bạn sẽ sử dụng các chỉ mục này để lập chỉ mục thành kp1kp2 và nhận được thành viên pt, là một bộ tọa độ của các tọa độ (x,y) xác định tọa độ không gian thực tế của các kết quả phù hợp.

Tất cả những gì bạn phải làm là lặp qua từng đối tượng cv2.DMatch trong matches, thêm vào danh sách tọa độ cho cả kp1kp2 và bạn đã hoàn tất.

Something như thế này:

# 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)) 

Lưu ý rằng tôi có thể vừa thực hiện list_kp1.append(kp1[img1_idx].pt) và tương tự cho list_kp2, nhưng tôi muốn làm cho nó rất rõ ràng về cách giải thích các tọa độ không gian. Bạn cũng có thể đi một bước xa hơn và làm một danh sách hiểu:

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

list_kp1 sẽ chứa các toạ độ không gian của một điểm tính năng phù hợp với vị trí tương ứng trong list_kp2. Nói cách khác, phần tử i của list_kp1 chứa tọa độ không gian của điểm đối tượng từ img1 khớp với điểm đối tượng tương ứng từ img2 trong list_kp2 tọa độ không gian có phần tử i.


Là một sidenote nhỏ, tôi đã sử dụng khái niệm này khi tôi đã viết một workaround cho drawMatches bởi vì đối với OpenCV 2.4.x, Python wrapper cho C++ chức năng không tồn tại, vì vậy tôi đã sử dụng khái niệm nêu trên trong định vị tọa độ không gian của các đối tượng địa lý phù hợp giữa hai hình ảnh để viết thực hiện của riêng tôi về nó.

Kiểm tra xem bạn có thích không!

module' object has no attribute 'drawMatches' opencv python

+3

Hơn bạn rất nhiều! – kotopanda

Các vấn đề liên quan