Matching ORB Features and Using Them to Find Homography

436 views Asked by At

I have a video and a template image and I want to extract an image that represents the template image. In my method, the results are not satisfying(the extracted image is juddering) and I could not be able to solve the problem. I am asking if there is any possible way to avoid paddling or another method to solve this problem.

  1. I found the features with the ORB and matched them.
  2. Used cv2.findHomography() function to get homography.
  3. Finally, used cv2.warpPerspective() function.
cap = cv2.VideoCapture('videos/gunduz/part1.mp4')
orb = cv2.ORB_create()  # Registration works with at least 50 points
im2 = cv2.imread('videos/gunduz/tmp1.jpg')
img2 = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)
kp2, des2 = orb.detectAndCompute(img2, None)

while True:
    success, im1 = cap.read()

    img1 = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY)

    # find the keypoints and descriptors with orb
    kp1, des1 = orb.detectAndCompute(img1, None)  # kp1 --> list of keypoints

    matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING)

    # Match descriptors.
    matches = matcher.match(des1, des2, None)  # Creates a list of all matches, just like keypoints

    # Sort them in the order of their distance.
    matches = sorted(matches, key=lambda x: x.distance)

    img3 = cv2.drawMatches(im1, kp1, im2, kp2, matches[:], None)

    cv2.imshow("Matches image", img3)

    points1 = np.zeros((len(matches), 2), dtype=np.float32)  # Prints empty array of size equal to (matches, 2)
    points2 = np.zeros((len(matches), 2), dtype=np.float32)

    for i, match in enumerate(matches[:]):
        points1[i, :] = kp1[match.queryIdx].pt  # gives index of the descriptor in the list of query descriptors
        points2[i, :] = kp2[match.trainIdx].pt  # gives index of the descriptor in the list of train descriptors

    h, mask = cv2.findHomography(points1, points2, cv2.RANSAC)  # You can also use 8 point.

    # Use homography
    height, width, channels = im2.shape
    im1Reg = cv2.warpPerspective(im1, h, (width, height))  # Applies a perspective transformation to an image.

    cv2.imshow("Registered image", im1Reg)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

0

There are 0 answers