문제

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?

도움이 되었습니까?

해결책

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.

다른 팁

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)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top