Python: OpenCV findHomography input

Python: OpenCV findHomography input … here is a solution to the problem.

Python: OpenCV findHomography input

I’m trying to find a unidirectional matrix of two images for rgb and rotated using opencv in Python:

print(rgb.shape, rotated.shape)
H = cv2.findHomography(rgb, rotated)
print(H)

The error I get is

(1080, 1920, 3) (1080, 1920, 3)
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-37-26874dc47f1f> in <module>()
      1 print(rgb.shape, rotated.shape)
----> 2 H = cv2.findHomography(rgb, rotated)
      3 print(H)

error: OpenCV(3.4.1) C:\projects\opencv-python\opencv\modules\calib3d\src\fundam.cpp:372: error: (-5) The input arrays should be 2D or 3D point sets in function cv::findHomography

I also tried using cv2.findHomography(rgb[:,:,0], rotated[:,:,0]) to see if the channel or channel order is causing any problems, but it doesn’t even work with 2D matrices.

How should the input be?

Solution

cv2.findHomography() does not receive two images and returns H.

If you need to find H as np.arrays:, for two RGB images

import numpy as np
import cv2

def findHomography(img1, img2):

# define constants
    MIN_MATCH_COUNT = 10
    MIN_DIST_THRESHOLD = 0.7
    RANSAC_REPROJ_THRESHOLD = 5.0

# Initiate SIFT detector
    sift = cv2.xfeatures2d.SIFT_create()

# find the keypoints and descriptors with SIFT
    kp1, des1 = sift.detectAndCompute(img1, None)
    kp2, des2 = sift.detectAndCompute(img2, None)

# find matches
    FLANN_INDEX_KDTREE = 1
    index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
    search_params = dict(checks=50)

flann = cv2. FlannBasedMatcher(index_params, search_params)
    matches = flann.knnMatch(des1, des2, k=2)

# store all the good matches as per Lowe's ratio test.
    good = []
    for m, n in matches:
        if m.distance < MIN_DIST_THRESHOLD * n.distance:
            good.append(m)

if len(good) > MIN_MATCH_COUNT:
        src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
        dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)

H, _ = cv2.findHomography(src_pts, dst_pts, cv2. RANSAC, RANSAC_REPROJ_THRESHOLD)
        return H

else: raise Exception("Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT))

Note:

  • Test on Python 3 and OpenCV 3.4
  • You need the opencv-contrib-python package because SIFT has patent issues and has been removed from opencv-python
  • This gives the H matrix for converting img1 and overlaying it on img2. If you want to know how to do this, it’s here

Related Problems and Solutions