2017-05-04 92 views
1

我遵循OpenCV Feature Detection and Description tutorial并在OpenCV中使用SIFT和其他算法来查找2个图像之间的匹配特征点。据我所知,这些算法可以找到2个图像之间的相似区域。但我有兴趣确定不同或不相似的地区。

如何在两张图像上绘制所有不匹配的特征点?此外,我可以在这些非匹配点周围绘制边界,以便能够显示2幅图像中的哪些区域不同?OpenCV绘制非匹配点

我在Windows 7上使用Python代码,并从最新的OpenCV源代码构建。

+0

你能提供一些你的代码(特别是你为这两个图像生成关键点和描述符的部分,以及你在哪里做'匹配')? –

+0

我可以解决它..我张贴我的回答下面 –

+0

你仍然需要一些提示您的问题的第二部分? –

回答

0

原来是简单的列表操作任务。这里是我的Python代码

# code copied from 
# http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_feature_homography/py_feature_homography.html 

import numpy as np 
import cv2 
from matplotlib import pyplot as plt 
from scipy.spatial.distance import euclidean 

MIN_MATCH_COUNT = 10 

img1 = cv2.imread('Src.png',0) # queryImage 
img2 = cv2.imread('Dest.png',0) # trainImage 

# Initiate SIFT detector 
sift = cv2.xfeatures2d.SIFT_create() 

# find the keypoints and descriptors with SIFT 
kp1, des1 = sift.detectAndCompute(img1,None) 
kp2, des2 = sift.detectAndCompute(img2,None) 

FLANN_INDEX_KDTREE = 0 
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5) 
search_params = dict(checks = 50) 

flann = cv2.FlannBasedMatcher(index_params, search_params) 

matches = flann.knnMatch(des1,des2,k=2) 

# store all the good matches as per Lowe's ratio test. 
good = [] 
for m,n in matches: 
    if m.distance < 0.7*n.distance: 
     good.append(m) 

if len(good)>MIN_MATCH_COUNT: 
    src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2) 
    dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2) 

    kp1_matched=([ kp1[m.queryIdx] for m in good ]) 
    kp2_matched=([ kp2[m.trainIdx] for m in good ]) 

    kp1_miss_matched=[kp for kp in kp1 if kp not in kp1_matched] 
    kp2_miss_matched=[kp for kp in kp2 if kp not in kp2_matched] 

    # draw only miss matched or not matched keypoints location 
    img1_miss_matched_kp = cv2.drawKeypoints(img1,kp1_miss_matched, None,color=(255,0,0), flags=0) 
    plt.imshow(img1_miss_matched_kp),plt.show() 

    img2_miss_matched_kp = cv2.drawKeypoints(img2,kp2_miss_matched, None,color=(255,0,0), flags=0) 
    plt.imshow(img2_miss_matched_kp),plt.show() 

    M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0) 
    matchesMask = mask.ravel().tolist() 

    h,w = img1.shape 
    pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2) 
    dst = cv2.perspectiveTransform(pts,M) 

else: 
    print "Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT) 
    matchesMask = None 
2
  1. 画上两个图像的所有不匹配的特征点:

这个任务是非常简单的,一旦你知道了Matcher objects的结构产生来自匹配的两个描述符(matches = bf.match(des1,des2))。有关这个问题的2名匹配器对象的属性有以下几种:

  • DMatch.trainIdx:描述符的索引(或从列车图像关键点)在列车描述符
  • DMatch.queryIdx:描述符的索引(或从查询图像关键点)查询描述符

然后,知道该信息,并作为@uz air_syed说,这只是一个simple list operations task


  • 周围画不匹配点的边界:
  • 要做到这一点,我会做这样的事情:

    • 为每个非匹配点创建一个白色像素的黑色蒙版
    • 根据的密度的非匹配点的簇,扩张具有大内核(即15 x 15像素)。
    • Erode具有相同内核大小的掩码。
    • 最后,在掩码上应用findContours函数以获取不匹配点的边界。

    欲了解更多信息,你可以看看这个question and its answer

    希望它能让您走上正轨!