├── README.md └── orb_ransac.py /README.md: -------------------------------------------------------------------------------- 1 | # Image-Matching-by-ORB-Feature-Using-RANSAC 2 | 3 | Overview 4 | - 5 | In this program, when performing matching between images, RANSAC is applied to increase the reliability of matching using extracted ORB features. 6 | 7 | Environment 8 | - 9 | Python3
10 | OpenCV:3.4.3 11 | 12 | Procedure 13 | - 14 | 1. Load image file 15 | 1. Extraction of feature points & feature quantities with ORB 16 | 1. Application of RANSAC 17 | 1. Write feature points on the image Output of result 18 | 19 | Example of Result 20 | - 21 | ![rena-ransac](https://user-images.githubusercontent.com/43288669/61606127-c2c69c00-ac83-11e9-96b2-8be0ff3649b7.png) 22 | -------------------------------------------------------------------------------- /orb_ransac.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | from matplotlib import pyplot as plt 4 | 5 | MIN_MATCH_COUNT = 10 #Number of minimum required feature points 6 | good_match_rate = 0.15 7 | 8 | img1 = cv2.imread('./image1.png',0) # queryImage 9 | img2 = cv2.imread('./image2.png',0) # trainImage 10 | 11 | # Initiate ORB detector 12 | orb = cv2.ORB_create() 13 | 14 | # find the keypoints and descriptors with ORB 15 | kp1, des1 = orb.detectAndCompute(img1,None) 16 | kp2, des2 = orb.detectAndCompute(img2,None) 17 | 18 | # create BFmatcher object 19 | bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) 20 | #bf = cv2.BFMatcher(cv2.NORM_L1, crossCheck=False) 21 | # Match descriptors. 22 | matches = bf.match(des1,des2) 23 | 24 | 25 | matches = sorted(matches, key = lambda x:x.distance) 26 | good = matches[:int(len(matches) * good_match_rate)] 27 | 28 | if len(good)>MIN_MATCH_COUNT: 29 | src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2) 30 | dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2) 31 | 32 | M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0) 33 | matchesMask = mask.ravel().tolist() 34 | 35 | h,w = img1.shape 36 | pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2) 37 | dst = cv2.perspectiveTransform(pts,M) 38 | 39 | img2 = cv2.polylines(img2,[np.int32(dst)],True,255,3, cv2.LINE_AA) 40 | 41 | else: 42 | print ("Not enough matches are found - %d/%d") % (len(good),MIN_MATCH_COUNT) 43 | matchesMask = None 44 | 45 | draw_params = dict(matchColor = (0,255,0), # draw matches in green color 46 | singlePointColor = None, 47 | matchesMask = matchesMask, # draw only inliers 48 | flags = 2) 49 | 50 | img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params) 51 | 52 | plt.imshow(img3, 'gray'),plt.show() 53 | --------------------------------------------------------------------------------