Monday, 12 October 2020

How to I compute matching features between high resolution images?

I am trying to match SIFT features between two images which I have detected using OpenCV:

sift = cv2.xfeatures2d.SIFT_create()
kp, desc = sift.detectAndCompute(img, None)

The images both seem to contains lots of features, around 15,000 each, shown with the green dots.

enter image description here enter image description here

But after matching them I only retain 87 and some are outliers.

enter image description here

I'm trying to figure out if I'm doing something wrong. My code for matching the two images is:

def match(this_filename, this_desc, this_kp, othr_filename, othr_desc, othr_kp):

    E_RANSAC_PROB = 0.999
    F_RANSAC_PROB = 0.999
    E_PROJ_ERROR = 15.0
    F_PROJ_ERROR = 15.0
    LOWE_RATIO = 0.9
    # FLANN Matcher
    # FLANN_INDEX_KDTREE = 1 # 1? https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_matcher/py_matcher.html#basics-of-brute-force-matcher
    # index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
    # search_params = dict(checks=50)   # or pass empty dictionary
    # flann = cv2.FlannBasedMatcher(index_params, search_params)
    # matcherij = flann.knnMatch(this_desc, othr_desc, k=2)
    # matcherji = flann.knnMatch(othr_desc, this_desc, k=2)

    # BF Matcher
    this_matches = {}
    othr_matches = {}


    bf = cv2.BFMatcher()
    matcherij = bf.knnMatch(this_desc, othr_desc, k=2)
    matcherji = bf.knnMatch(othr_desc, this_desc, k=2)

    matchesij = []
    matchesji = []

    for i,(m,n) in enumerate(matcherij):
        if m.distance < LOWE_RATIO*n.distance:
            matchesij.append((m.queryIdx, m.trainIdx))

    for i,(m,n) in enumerate(matcherji):
        if m.distance < LOWE_RATIO*n.distance:
            matchesji.append((m.trainIdx, m.queryIdx))


    # Make sure matches are symmetric
    symmetric = set(matchesij).intersection(set(matchesji))
    symmetric = list(symmetric)

    this_matches[othr_filename] = [ (a, b) for (a, b) in symmetric ]
    othr_matches[this_filename] = [ (b, a) for (a, b) in symmetric ]

    src = np.array([ this_kp[index[0]].pt for index in this_matches[othr_filename] ])
    dst = np.array([ othr_kp[index[1]].pt for index in this_matches[othr_filename] ])

    if len(this_matches[othr_filename]) == 0:
        print("no symmetric matches")
        return 0

    # retain inliers that fit x.F.xT == 0
    F, inliers = cv2.findFundamentalMat(src, dst, cv2.FM_RANSAC, F_PROJ_ERROR, F_RANSAC_PROB)

    if F is None or inliers is None:
        print("no F matrix estimated")
        return 0

    inliers = inliers.ravel()

    this_matches[othr_filename] = [ this_matches[othr_filename][x] for x in range(len(inliers)) if inliers[x] ]
    othr_matches[this_filename] = [ othr_matches[this_filename][x] for x in range(len(inliers)) if inliers[x] ]

    return this_matches, othr_matches, inliers.sum()

Here are the two original images: https://www.dropbox.com/s/pvi247be2ds0noc/images.zip?dl=0



from How to I compute matching features between high resolution images?

No comments:

Post a Comment