Repository: opencv
Issue: Bug in DescriptorMatcher.match()
Labels: category: python bindings

##### System information (version)
<!-- Example
- OpenCV => 4.2
- Operating System / Platform => Windows 64 Bit
- Compiler => Visual Studio 2017
-->

- OpenCV => 4.4
- Operating System / Platform => Windows 10 64 Bit

I'm setting up a brute force matcher like this:

```bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)```

However, when I try to run ```best_matches = bf.match(queryDescriptors=featuresA, trainDescriptors=featuresB, masks=masks)``` I get error ```TypeError: DescriptorMatcher.match() takes at most 2 arguments (3 given)```

The documentation here (https://docs.opencv.org/3.4/db/d39/classcv_1_1DescriptorMatcher.html#a3cc074710ccb466a662815969e14cf5e) 
clearly says the function accepts three arguments:

```matches  =   cv.DescriptorMatcher.match( queryDescriptors, trainDescriptors[, mask]  )```

To reproduce you'll need feature vectors from two images (featuresA, featuresB), as well as an array that is len(featuresA) x len(featuresB). I can upload stuff or you can use your own. Full code here:

```
import cv2
import numpy as np
import matplotlib.pyplot as plt
import imageio
import imutils
cv2.ocl.setUseOpenCL(False)

orb = cv2.ORB_create()

folder = Path('C:/Users/hughr/docs_local/fire_frames/sample_pano')
image_fns = list(folder.glob('*.jpg'))
gray_images = [cv2.cvtColor(imageio.imread(x), cv2.COLOR_RGB2GRAY) for x in image_fns]
num_images = len(gray_images)
gray_images.append(gray_images[0])

kpsA = []
kpsB = []
featuresA = []
featuresB = []
for i in np.arange(num_images):
    kps, features = orb.detectAndCompute(gray_images[i], None)
    kpsA.append(kps)
    featuresA.append(features)
    if i == (num_images-1): i = -1
    kps, features = orb.detectAndCompute(gray_images[i+1], None)
    kpsB.append(kps)
    featuresB.append(features)



def matchKeyPointsBF(kpsA, kpsB, featuresA, featuresB, method):
    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=crossCheck)
    kpsA_array = np.array([x.pt for x in kpsA]).reshape(-1, 1, 2)
    kpsB_array = np.array([x.pt for x in kpsB]).reshape(-1, 1, 2)
    
    masks = np.zeros((kpsA_array.shape[0], kpsB_array.shape[0])).astype(np.uint8)
    # Match descriptors.
    for i in np.arange(kpsA_array.shape[0]):

        H = H_estval
        kpsB_transformed = cv2.perspectiveTransform(kpsB_array, H)
        distances = np.sqrt((kpsA_array[0, 0, 0] - kpsB_transformed[:, 0, 0])**2 + 
                            (kpsA_array[0, 0, 1] - kpsB_transformed[:, 0, 1])**2)
        distances = np.hstack((distances.reshape(-1, 1), np.arange(distances.shape[0]).reshape(-1,1)))
        close_ones_idx = distances[distances[:, 0] <500]
        print(close_ones_idx.shape)
        masks[i, close_ones_idx[:,1].astype(np.int64)] = 1
    
    best_matches = bf.match(queryDescriptors=featuresA, trainDescriptors=featuresB) #, masks=masks)
    matches = sorted(best_matches, key = lambda x:x.distance)       

    print("Retained:", len(matches))
    return matches

matches = []
feature_extractor = 'orb' # one of 'sift', 'surf', 'brisk', 'orb'
feature_matching = 'bf' # knn or bf

for i in np.arange(num_images):
    ms = matchKeyPointsBF(kpsA[i], kpsB[i], featuresA[i], featuresB[i], method=feature_extractor)
    matches.append(ms)
    if len(ms) == 0: continue



```