Abhishek
Abhishek

Reputation: 41

Unstable homography estimation using ORB

I am developing a feature tracking application and so far, after trying to almost all the feature detectors/descriptors, i've got the most satisfactory overall results with ORB. Both my feature descriptor and detector is ORB.

I am selecting a specific area for detecting features on my source image (by masking). and then matching it with features detected on subsequent frames.

Then i filter my matches by performing ratio test on 'matches' obtained from the following code:

std::vector<std::vector<DMatch>> matches1;

m_matcher.knnMatch( m_descriptorsSrcScene, m_descriptorsCurScene, matches1,2 );

I also tried the two way ratio test(filtering matches from Source to Current scene and vice-versa, then filtering out common matches) but it didn't do much, so I went ahead with the one way ratio test.

i also add a min distance check to my ratio test, which, it apppears, gives better results

if (distanceRatio < m_fThreshRatio && bestMatch.distance < 5*min_dist)
{
    refinedMatches.push_back(bestMatch);
}

and in the end , i estimate the Homography.

Mat H = findHomography(points1,points2);

I've tried using the RANSAC method for estimating inliners and then using those to recalculate my Homography, but that gives more unstability plus consumes more time.

then in the end i draw a rectangle around my specific region which is to be tracked. i get the plane coordinates by:

perspectiveTransform( obj_corners, scene_corners, H);

where 'objcorners' are the coordinates of my masked(or unmasked) region.

The reactangle I draw using 'scene_corners' seems to be vibrating. increasing the number of features has reduced it quite a bit, but I cant increase them too much because of the time constraint.

How can i improve the stability?

Any suggestions would be appreciated.

Thanks.

Upvotes: 1

Views: 2621

Answers (2)

samfr
samfr

Reputation: 666

If it is the vibrations that are really bothersome to you then you could try taking the moving average of the homography matrices over time:

cv::Mat homoG = cv::findHomography(obj, scene, CV_RANSAC);
if (homography.empty()) {
    homoG.copyTo(homography);
}
cv::accumulateWeighted(homoG, homography, 0.1);

Make the 'homography' variable global, and keep calling this every time you get a new frame. The alpha parameter of accumulateWeighted is the reciprocal of the period of the moving average.

So 0.1 is taking the average of the last 10 frames and 0.2 is taking the average of the last 5 and so on...

Upvotes: 1

DevGoldm
DevGoldm

Reputation: 828

A suggestion that comes to mind from experience with feature detection/matching is that sometimes you just have to accept the matched feature points will not work perfectly. Even subtle changes in the scene you are looking at can cause somewhat annoying problems, for example changes in light or unwanted objects coming into view.

It appears to me that you have a decently working feature matching in place from what you say, you may want to work on a way of keeping the region of interest constant. If you know the typical speed or any other movement patterns unique to any object you are trying to track between frames, or any constraints relating to the position of your camera, it may be useful in avoiding recalculating the region of interest unnecessarily causing vibrations. Or in fact it may help in creating a more efficient searching algorithm, allowing you to increase the number of feature points you can detect and use.

Another (small) hack you can use is to avoid redrawing the region window if the previous window was of similar size and position.

Upvotes: 0

Related Questions