Draw good matches after RanSaC in green and discarded matches in red

asked 2017-07-18 05:14:37 -0500

swiss_knight gravatar image

updated 2017-07-18 05:32:41 -0500

berak gravatar image

For an image pair, I'd like first to draw all matches according to Lowe's distance ratio.

Then, I'd like to filter them using a RanSaC homography.

Up to this point I'm ok.

But I'd like to represent all the matches kept after RanSaC with green lines and all the discarded matches in red on the same image pair.

How could I achieve that?


Here's part of my code yet, assuming I already have SIFT kp and desc for both image1 and image2 from a previous processing step and where I save results before and after RanSaC in two separate files for the moment:

        FLANN_INDEX_KDTREE = 1
        index_params  = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
        search_params = dict(checks=50)
        flann = cv2.FlannBasedMatcher(index_params, search_params)

        matches = flann.knnMatch(desc1, desc2, k=2) 

        # Create a mask to draw only good matches:
        matchesMask = [[0,0] for j in xrange(len(matches))]

        # Ratio test as per Lowe's 2004 paper:
        gooddist  = []
        pts1 = []
        pts2 = []
        for a,(m,n) in enumerate(matches): # 1st and 2nd NN matches
            if m.distance < 0.7*n.distance: # play with ratio... 
                matchesMask[a] = [1,0]
                gooddist.append(m)           

        good = gooddist

        if len(good)>=6: 
            src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ])
            dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ])
            homog_method      = cv2.RANSAC
            homog_reprojthres = 5.0
            homog_mask        = None
            homog_max_iter    = 2000
            homog_confidence  = 0.995
            M, mask = cv2.findHomography(src_pts, dst_pts, homog_method, homog_reprojthres, homog_mask, homog_max_iter, homog_confidence)
            matchesMask2 = mask.ravel().tolist()


            draw_params3 = dict(matchColor = (0,255,255), # yellow
                               #singlePointColor = (20,255,200) if not loadSIFT else (255,220,20),
                                matchesMask = matchesMask, # draw only good inliers points
                                flags = 2) # Before RANSAC 

            draw_params4 = dict(matchColor = (0,255,0), # green
                                singlePointColor = None,
                                matchesMask = matchesMask2, # draw only good inliers points
                                flags = 2) # After RANSAC                  

            img1   = cv2.imread(imgfile1, 1) # 1:= color-mode                
            img2   = cv2.imread(imgfile2, 1) # 1:= color-mode

            img3  = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,**draw_params3)
            cv2.imwrite(file_nameA_on_disk, img3)

            img4  = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params4)
            cv2.imwrite(file_nameB_on_disk, img4)

Reference for SIFT: https://www.robots.ox.ac.uk/~vgg/rese...

edit retag flag offensive close merge delete

Comments

I am not really seeing the problem. Once you have performed ransac, you will have a set of filtered keypoints. The other matches you already had. Just call the drawing function twice, first the red one for all matches, then the green one for only the good matches. Be sure to do it on the same matrix, so that it is encoded in a single image.

StevenPuttemans gravatar imageStevenPuttemans ( 2017-07-18 07:39:43 -0500 )edit