Question

I am trying to use drawmatches function in OpenCV.

It put the image in left and right format. I want the images to be put in top-down format and then draw the matches for more clarity.

Is there a way in which it can be done in OpenCV? Or, I will have to write a new function?

Was it helpful?

Solution

I am afraid you have to write your own function. I think it should not be too complicated.

As a starting point just have a look at https://github.com/Itseez/opencv/blob/2.4/modules/features2d/src/draw.cpp where we have the function _prepareImgAndDrawKeypoints

static void _prepareImgAndDrawKeypoints( const Mat& img1, const vector<KeyPoint>& keypoints1,
                                         const Mat& img2, const vector<KeyPoint>& keypoints2,
                                         Mat& outImg, Mat& outImg1, Mat& outImg2,
                                         const Scalar& singlePointColor, int flags )
{
    Size size( img1.cols + img2.cols, MAX(img1.rows, img2.rows) );

for example size should be changed to

Size size( MAX(img1.cols + img2.cols), img1.rows + img2.rows );

and then you can continue to study that function (and the other ones) and complete your task. Maybe you can also contribute to OpenCV too with your new feature.

OTHER TIPS

As a quick workaround, you can pre-rotate both images 90 degrees, detect features, draw the matches and then undo the rotation,

As an example, have these images (taken from here and here):

im1 im2

Result:

enter image description here

Python code : (the resize part is just for fitting the images to the screen size)

import cv2

im1 = cv2.imread('test1.jpg')
im2 = cv2.imread('test2.jpg')

# resize
scale=0.5
n1,m1 = int(im1.shape[0]*scale), int(im1.shape[1]*scale)
n2,m2 = int(im2.shape[0]*scale), int(im2.shape[1]*scale)
im1 = cv2.resize(im1, (m1,n1))
im2 = cv2.resize(im2, (m2,n2))

rotate=True
if rotate:
    im1 = cv2.rotate(im1, cv2.ROTATE_90_COUNTERCLOCKWISE)
    im2 = cv2.rotate(im2, cv2.ROTATE_90_COUNTERCLOCKWISE)
    
# gray versions:
im1g = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY)
im2g = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)

# sift detections:
sift = cv2.SIFT_create()
kp1, ds1 = sift.detectAndCompute(im1g,None)
kp2, ds2 = sift.detectAndCompute(im2g,None)

# matching
matcher = cv2.DescriptorMatcher.create('BruteForce')
matches = matcher.knnMatch(ds1,ds2, 2)
# Filter matches using the Lowe's ratio test
ratio_thresh = 0.7
good_matches = []
for i, (m,n) in enumerate(matches):
    if m.distance < ratio_thresh * n.distance:
        good_matches.append(m)
        
# draw matches:
im_matches = cv2.drawMatches(im1, kp1, im2, kp2, good_matches,None, 
                             flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
# undo pre-rotation
if rotate:
    im_matches = cv2.rotate(im_matches, cv2.ROTATE_90_CLOCKWISE)
cv2.imshow('matches', im_matches)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top