def findMatchesBetweenImages(image_1, image_2, num_matches): """ Return the top list of matches between two input images. Note: You will not be graded for this function. This function is almost identical to the function in Assignment 7 (we just parametrized the number of matches). We expect you to use the function you wrote in A7 here. We will also release a solution for how to do this after A7 submission has closed. If your code from A7 was wrong, don't worry, you will not lose points in this assignment because your A7 code was wrong (hence why we will provide a solution for you after A7 closes). This function detects and computes SIFT (or ORB) from the input images, and returns the best matches using the normalized Hamming Distance through brute force matching. Args: image_1 (numpy.ndarray): The first image (grayscale). image_2 (numpy.ndarray): The second image. (grayscale). num_matches (int): The number of desired matches. If there are not enough, return as many matches as you can. Returns: image_1_kp (list): The image_1 keypoints, the elements are of type cv2.KeyPoint. image_2_kp (list): The image_2 keypoints, the elements are of type cv2.KeyPoint. matches (list): A list of matches, length 'num_matches'. Each item in the list is of type cv2.DMatch. If there are less matches than num_matches, this function will return as many as it can. """ # matches - type: list of cv2.DMath matches = None # image_1_kp - type: list of cv2.KeyPoint items. image_1_kp = None # image_1_desc - type: numpy.ndarray of numpy.uint8 values. image_1_desc = None # image_2_kp - type: list of cv2.KeyPoint items. image_2_kp = None # image_2_desc - type: numpy.ndarray of numpy.uint8 values. image_2_desc = None # COPY YOUR CODE FROM A7 HERE. sift = SIFT() image_1_kp, des1 = sift.detectAndCompute(image_1, None) image_2_kp, des2 = sift.detectAndCompute(image_2, None) bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) matches = bf.match(des1, des2) matches = sorted(matches, key = lambda x:x.distance) # We coded the return statement for you. You are free to modify it -- just # make sure the tests pass. return image_1_kp, image_2_kp, matches[:num_matches]
def findMatchesBetweenImages(image_1, image_2): """ Return the top 10 list of matches between two input images. This function detects and computes SIFT (or ORB) from the input images, and returns the best matches using the normalized Hamming Distance. Follow these steps: 1. Compute SIFT keypoints and descriptors for both images 2. Create a Brute Force Matcher, using the hamming distance (and set crossCheck to true). 3. Compute the matches between both images. 4. Sort the matches based on distance so you get the best matches. 5. Return the image_1 keypoints, image_2 keypoints, and the top 10 matches in a list. Note: We encourage you use OpenCV functionality (also shown in lecture) to complete this function. Args: image_1 (numpy.ndarray): The first image (grayscale). image_2 (numpy.ndarray): The second image. (grayscale). Returns: image_1_kp (list): The image_1 keypoints, the elements are of type cv2.KeyPoint. image_2_kp (list): The image_2 keypoints, the elements are of type cv2.KeyPoint. matches (list): A list of matches, length 10. Each item in the list is of type cv2.DMatch. """ # matches - type: list of cv2.DMath matches = None # image_1_kp - type: list of cv2.KeyPoint items. image_1_kp = None # image_1_desc - type: numpy.ndarray of numpy.uint8 values. image_1_desc = None # image_2_kp - type: list of cv2.KeyPoint items. image_2_kp = None # image_2_desc - type: numpy.ndarray of numpy.uint8 values. image_2_desc = None # WRITE YOUR CODE HERE. sift = SIFT() image_1_kp, image_1_desc = sift.detectAndCompute(image_1, None) image_2_kp, image_2_desc = sift.detectAndCompute(image_2, None) bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) matches = bf.match(image_1_desc, image_2_desc) matches = sorted(matches, key = lambda x: x.distance) matches = matches[:10] # We coded the return statement for you. You are free to modify it -- just # make sure the tests pass. return image_1_kp, image_2_kp, matches
def findMatchesBetweenImages(image_1, image_2): """ Return the top 10 list of matches between two input images. This function detects and computes SIFT (or ORB) from the input images, and returns the best matches using the normalized Hamming Distance. Args: image_1 (numpy.ndarray): The first image (grayscale). image_2 (numpy.ndarray): The second image. (grayscale). Returns: image_1_kp (list): The image_1 keypoints, the elements are of type cv2.KeyPoint. image_2_kp (list): The image_2 keypoints, the elements are of type cv2.KeyPoint. matches (list): A list of matches, length 10. Each item in the list is of type cv2.DMatch. """ # matches - type: list of cv2.DMath matches = None # image_1_kp - type: list of cv2.KeyPoint items. image_1_kp = None # image_1_desc - type: numpy.ndarray of numpy.uint8 values. image_1_desc = None # image_2_kp - type: list of cv2.KeyPoint items. image_2_kp = None # image_2_desc - type: numpy.ndarray of numpy.uint8 values. image_2_desc = None # WRITE YOUR CODE HERE. #init sift = SIFT() #1. Compute SIFT keypoints and descriptors for both images image_1_kp, image_1_desc = sift.detectAndCompute(image_1, None) image_2_kp, image_2_desc = sift.detectAndCompute(image_2, None) #2. Create a Brute Force Matcher, using the hamming distance (and set crossCheck to true). #create BFMatcher object bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) #3. Compute the matches between both images. #match descriptors matches = bf.match(image_1_desc, image_2_desc) #4. Sort the matches based on distance so you get the best matches. matches = sorted(matches, key=lambda x: x.distance) #5. Return the image_1 keypoints, image_2 keypoints, and the top 10 matches in a list. return image_1_kp, image_2_kp, matches[:10]
def findMatchesBetweenImages(image_1, image_2, num_matches, mask_offset, mask_size): """ Return the top list of matches between two input images. Args: ---------- image_1 : numpy.ndarray The first image (can be a grayscale or color image) image_2 : numpy.ndarray The second image (can be a grayscale or color image) num_matches : int The number of desired matches. If there are not enough, return as many matches as you can. Returns: ---------- image_1_kp : list[cv2.KeyPoint] A list of keypoint descriptors in the first image image_2_kp : list[cv2.KeyPoint] A list of keypoint descriptors in the second image matches : list[cv2.DMatch] A list of matches between the keypoint descriptor lists of length no greater than num_matches """ matches = None # type: list of cv2.DMath image_1_kp = None # type: list of cv2.KeyPoint items image_1_desc = None # type: numpy.ndarray of numpy.uint8 values. image_2_kp = None # type: list of cv2.KeyPoint items. image_2_desc = None # type: numpy.ndarray of numpy.uint8 values. orb = ORB() offset = (mask_offset[0] * image_1.shape[0], mask_offset[1] * image_1.shape[1]) size = (mask_size[0] * image_1.shape[0], mask_size[1] * image_1.shape[1]) mask = np.zeros(image_1.shape[:2], dtype=np.uint8) mask[int(offset[0] - size[0] / 2):int(offset[0] + size[0] / 2), int(offset[1] - size[1] / 2):int(offset[1] + size[1] / 2)] = 255 image_1_kp, image_1_desc = orb.detectAndCompute(image_1, mask) image_2_kp, image_2_desc = orb.detectAndCompute(image_2, mask) bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) matches = bf.match(image_1_desc, image_2_desc) matches = sorted(matches, key=lambda x: x.distance)[:num_matches] return image_1_kp, image_2_kp, matches
def findMatchesBetweenImages(image_1, image_2, num_matches): matches = None image_1_kp = None image_1_desc = None image_2_kp = None image_2_desc = None sift = SIFT() image_1_kp, image_1_desc = sift.detectAndCompute(image_1, None) image_2_kp, image_2_desc = sift.detectAndCompute(image_2, None) bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) matches = bf.match(image_1_desc, image_2_desc) matches = sorted(matches, key=lambda x: x.distance) matches = matches[:num_matches] return image_1_kp, image_2_kp, matches
def orb_detect_and_compute_by_part(orb: cv2.ORB, img: np.ndarray, part: t.Tuple[int, int] = (5, 5)): height, width = img.shape dh, dw = height // part[0] + 1, width // part[1] + 1 final_des = [] for h in range(0, height, dh): mh = min(h + dh, height) for w in range(0, width, dw): mw = min(w + dw, width) crop = img[h:mh, w:mw] _, des = orb.detectAndCompute(crop, None) if des is not None: final_des.extend(des) return np.array(final_des, dtype="uint8")
def findMatchesBetweenImages(img1, img2): """ This function detects and computes SIFT (or ORB) from the input images, and returns the best matches using the normalized Hamming Distance. """ img1 = cv2.blur(img1,(2, 2)) img1 = cv2.Canny(img1,100, 200) img2 = cv2.blur(img2,(2, 2)) img2 = cv2.Canny(img2,100, 200) #img1 = cv2.Sobel(img1,cv2.CV_8U, 1,0, ksize=5) #img2 = cv2.Sobel(img2,cv2.CV_8U, 1,0, ksize=5) # matches - type: list of cv2.DMath matches = None # image_1_kp - type: list of cv2.KeyPoint items. kp1 = None # image_1_desc - type: numpy.ndarray of numpy.uint8 values. desc1 = None # image_2_kp - type: list of cv2.KeyPoint items. kp2 = None # image_2_desc - type: numpy.ndarray of numpy.uint8 values. desc2 = None # Code modified from: # http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html # Code also pulled from 'feature_matching.zip' # print 'DTYPE', image_1.dtype # Initialize ORB detector object orb = SIFT() # or cv2.SIFT() in OpenCV 2.4.9+ # Find keypoints, compute descriptors and show them on original image (with scale and orientation) kp1, desc1 = orb.detectAndCompute(img1, None) kp2, desc2 = orb.detectAndCompute(img2, None) print "Image 1: {} keypoints found".format(len(kp1)) print "Image 2: {} keypoints found".format(len(kp2)) if KNN_MATCH: ##################################### # FLANN parameters desc1 = desc1.astype('float32') desc2 = desc2.astype('float32') FLANN_INDEX_KDTREE = 0 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) all_matches = flann.knnMatch(desc1, desc2, k=2) matches = [] for m,n in all_matches: if m.distance < 0.75*n.distance: matches.append([m]) #print matches ##################################### else: ##################################### # Create BFMatcher (Brute Force Matcher) object bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) # Match descriptors matches = bf.match(desc1, desc2) print "{} matches found".format(len(matches)) # Sort them in the order of their distance matches = sorted(matches, key = lambda x: x.distance) matches = matches[:10] print 'DMatch.distance - Distance between descriptors. The lower, the better it is:' for x in matches: print x.distance, print '\n' ##################################### return kp1, kp2, matches
# one = np.array([1]) # zero = np.array([0]) # ones = np.tile(one, [height, width/2]) # zeros = np.tile(zero, [height, width - ones.shape[1]]) # maskLeft = np.concatenate((zeros, ones), axis = 1) # maskRight = np.concatenate((ones, zeros), axis = 1) # # print maskRight.astype(np.int8) # kp1L, des1L = SIFT.detectAndCompute(img1,maskRight.astype(np.int8)) # kp1R, des1R = SIFT.detectAndCompute(img1,maskLeft.astype(np.int8)) # kp1 = kp1L + kp1R # des1 = des1L + des1R # print len(kp1L), len(kp1) #=============================================================================== kp1, des1 = SIFT.detectAndCompute(img1,None) kp2, des2 = SIFT.detectAndCompute(img2,None) FLANN_INDEX_LSH = 6 index_params= dict(algorithm = FLANN_INDEX_LSH, table_number = 6, # 12 key_size = 12, # 20 multi_probe_level = 1) #2 search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params,search_params) matches = flann.knnMatch(des1,des2,k=2)
def findMatchesBetweenImages(image_1, image_2): """ Return the top 10 list of matches between two input images. This function detects and computes SIFT (or ORB) from the input images, and returns the best matches using the normalized Hamming Distance. Follow these steps: 1. Compute SIFT keypoints and descriptors for both images 2. Create a Brute Force Matcher, using the hamming distance (and set crossCheck to true). 3. Compute the matches between both images. 4. Sort the matches based on distance so you get the best matches. 5. Return the image_1 keypoints, image_2 keypoints, and the top 10 matches in a list. Note: We encourage you use OpenCV functionality (also shown in lecture) to complete this function. Args: image_1 (numpy.ndarray): The first image (grayscale). image_2 (numpy.ndarray): The second image. (grayscale). Returns: image_1_kp (list): The image_1 keypoints, the elements are of type cv2.KeyPoint. image_2_kp (list): The image_2 keypoints, the elements are of type cv2.KeyPoint. matches (list): A list of matches, length 10. Each item in the list is of type cv2.DMatch. """ # matches - type: list of cv2.DMath matches = None # image_1_kp - type: list of cv2.KeyPoint items. image_1_kp = None # image_1_desc - type: numpy.ndarray of numpy.uint8 values. image_1_desc = None # image_2_kp - type: list of cv2.KeyPoint items. image_2_kp = None # image_2_desc - type: numpy.ndarray of numpy.uint8 values. image_2_desc = None # create SIFT object sift = SIFT() # compute the keypoints & descriptors image_1_kp, image_1_desc = sift.detectAndCompute(image_1, None) image_2_kp, image_2_desc = sift.detectAndCompute(image_2, None) # when false, will perform an alternative algorithm for checking neighbors crosscheck = False # create Brute Force Matcher object for computing hamming distances matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crosscheck) if crosscheck is True: matches_good = matcher.match(image_1_desc, image_2_desc) else: # compute the matches while applying the ratio test along the way according # to the distance with a matche's nearest neighbor. # See section 7.1 in https://www.cs.ubc.ca/~lowe/papers/ijcv04.pdf thresh = 0.55 matches_good = list() mm = matcher.knnMatch(image_1_desc, image_2_desc, k=2) # make sure we get at least 20 matches, where most of the false positives # are filtered out while len(matches_good) < 20: for m, n in mm: if m.distance / n.distance < thresh: matches_good.append(m) thresh += 0.01 # sort in ascending order by distance - only keep the top 10 matches = sorted(matches_good, key=lambda m: m.distance)[:10] return image_1_kp, image_2_kp, matches
def test_ORB(self): from cv2 import ORB test_orb = ORB()