Updated by Alexander Shishkov almost 13 years ago

The cv::findHomography function lacks a parameter to control the number of RANSAC iterations. OpenCV by default sets it to a max of 2000. If there is truly a match between the src and dst image then the number of iterations performed is much lower in practice (due to adaptive calculation). The converse is true, if there are no valid matches then you're likely to reach 2000 iterations. This is a problem if you need it to run within a fixed amount of time eg. for real-time.

Here is the result of my own testing using the following code:

<pre><code class="cpp">

#include <opencv2/calib3d/calib3d.hpp>
#include <iostream>
#include <cstdio>
#include <sys/time.h>
#include <numeric>

double TimeDiff(timeval t1, timeval t2)
{
double t;
t = (t2.tv_sec - t1.tv_sec) * 1000.0; // sec to ms
t += (t2.tv_usec - t1.tv_usec) / 1000.0; // us to ms

return t;
}

int main()
{
// number of matches
int n = 20;

// imaginary image
int w = 640;
int h = 480;

cv::Mat src(n, 2, CV_32F);
cv::Mat dst(n, 2, CV_32F);

for(int i=0; i < n; i++) {
src.at<float>(i,0) = w*(rand()/(1.0+RAND_MAX));
src.at<float>(i,1) = h*(rand()/(1.0+RAND_MAX));

dst.at<float>(i,0) = w*(rand()/(1.0+RAND_MAX));
dst.at<float>(i,1) = h*(rand()/(1.0+RAND_MAX));
}

timeval t1, t2;
std::vector <uchar> mask;

gettimeofday(&t1, NULL);
cv::findHomography(src, dst, CV_RANSAC, 3.0, mask);
gettimeofday(&t2, NULL);

std::cout << "inliers = " << std::accumulate(mask.begin(), mask.end(), 0) << endl;
std::cout << TimeDiff(t1,t2) << " ms" << std::endl;
}
</code></pre>


The code above will produce a src/dst matrix that will have NO valid matches. Running this I get

inliers = 5
75.93 ms

The number of RANSAC iteration done was 1354 (I modified the [[OpenCV]] code to print it out). For some real-time application, 75ms and above is too high. It would be nice to allow the user to choose the maximum number of iterations, suited for their needs.

It is trivial to add an extra parameter with a default value to cvFindHomography eg.
<pre><code class="cpp">


CV_IMPL int
cvFindHomography( const CvMat* objectPoints, const CvMat* imagePoints, CvMat* H, +H, int method, double ransacReprojThreshold, CvMat* mask, int maxiters )
</code></pre>


and the best part is it won't break anything! (shouldn't anyway)

Back