import numpy as np
import matplotlib.pyplot as plt
def drawMatches(img1, kp1, img2, kp2, matches):"""
My own implementation of cv2.drawMatches as OpenCV 2.4.9
does not have this function available but it's supported in
This function takes in two images with their associated
keypoints, as well as a list of DMatch data structure (matches)
that contains which keypoints matched in which images.
An image will be produced where a montage is shown with
the first image followed by the second image beside it.
Keypoints are delineated with circles, while lines are connected
between matching keypoints.
img1,img2 - Grayscale images
kp1,kp2 - Detected list of keypoints through any of the OpenCV keypoint
matches - A list of matches of corresponding keypoints through any
OpenCV keypoint matching algorithm
"""# Create a new output image that concatenates the two images together# (a.k.a) a montage
rows1 = img1.shape
cols1 = img1.shape
rows2 = img2.shape
cols2 = img2.shape
out = np.zeros((max([rows1,rows2]),cols1+cols2,3), dtype='uint8')# Place the first image to the left
out[:rows1,:cols1]= np.dstack([img1, img1, img1])# Place the next image to the right of it
out[:rows2,cols1:]= np.dstack([img2, img2, img2])# For each pair of points we have between both images# draw circles, then connect a line between themfor mat in matches:# Get the matching keypoints for each of the images
img1_idx = mat.queryIdx
img2_idx = mat.trainIdx
# x - columns# y - rows(x1,y1)= kp1[img1_idx].pt
# Draw a small circle at both co-ordinates# radius 4# colour blue# thickness = 1
cv2.circle(out,(int(x2)+cols1,int(y2)),4,(255,0,0),1)# Draw a line in between the two points# thickness = 1# colour blue
cv2.line(out,(int(x1),int(y1)),(int(x2)+cols1,int(y2)),(255,0,0),1)# Show the image
cv2.imshow('Matched Features', out)
cv2.destroyWindow('Matched Features')# Also return the image if you'd like a copyreturn out
img1 = cv2.imread('box.png',0)# queryImage
img2 = cv2.imread('box_in_scene.png',0)# trainImage# Initiate SIFT detector
orb = cv2.ORB()# find the keypoints and descriptors with SIFT
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)# Match descriptors.
matches = bf.match(des1,des2)# Draw first 10 matches.
img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10], flags=2)