Example #1
0
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]
Example #2
0
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
Example #3
0
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]
Example #4
0
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
Example #5
0
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
Example #6
0
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")
Example #7
0
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
Example #8
0
# 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)


Example #9
0
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
Example #10
0
 def test_ORB(self):
     from cv2 import ORB
     test_orb = ORB()