OpenCV Q&A Forum - RSS feedhttp://answers.opencv.org/questions/OpenCV answersenCopyright <a href="http://www.opencv.org">OpenCV foundation</a>, 2012-2018.Fri, 14 Sep 2018 04:26:23 -0500Compute inliers for a homographyhttp://answers.opencv.org/question/12295/compute-inliers-for-a-homography/I am trying to compute the inliers of a homography found using RANSAC by myself, but I never get the exact same list than the one given by the mask. Here are two codes that I wrote. Both use the same Homography matrix *cv::Mat H*.
Using **findHomography**(), I get a *mask* as output and I can print the id of the inliers using the following code:
// Somewhere before I did: findHomography(points1, points2, CV_RANSAC, 3, mask)
for (int i = 0; i < nbMatchings; i++)
{
// Select only the inliers (mask entry set to 1)
if ((int)mask.at<uchar>(i, 0) == 1)
{
std::cout << i << ", ";
}
}
std::cout << std::endl;
Then, supposing I want to compute the inliers myself (without using *cv::Mat mask*), and by computing the distance between a point and its correspondence using the very same code as in ***modules/calib3d/src/fundam.cpp***:
for (int i = 0; i < nbMatchings; i++)
{
// cv::Mat H is filled by findHomography(points1, points2, CV_RANSAC, 3, mask)
const double* H2 = H.ptr<double>();
float Hf[] = { (float)H2[0], (float)H2[1], (float)H2[2], (float)H2[3], (float)H2[4], (float)H2[5], (float)H2[6], (float)H2[7] };
float ww = 1.f/(Hf[6]*points1[i].x + Hf[7]*points1[i].y + 1.f);
float dx = (Hf[0]*points1[i].x + Hf[1]*points1[i].y + Hf[2])*ww - points2[i].x;
float dy = (Hf[3]*points1[i].x + Hf[4]*points1[i].y + Hf[5])*ww - points2[i].y;
float dist = (float)(dx*dx + dy*dy);
if (dist <= 9) // The threshold used for RANSAC is 3, so the squared distance is 9
{
std::cout << i << ", ";
}
}
std::cout << std::endl;
Both codes work, and almost give the same results. The point is that in my understanding, it should result exactly in the same list in both codes, and it is obviously not. Usually, the second code outputs up to 10% more inliers than the first code. But some inliers are in the first list and not in the second whilst some are in the second and not in the first.
Does anybody have an idea about this problem? Why is it the case that, using the very same Homography matrix (it is computed only once), I don't get the same inliers twice? Wed, 24 Apr 2013 07:49:52 -0500http://answers.opencv.org/question/12295/compute-inliers-for-a-homography/Answer by hayley for <p>I am trying to compute the inliers of a homography found using RANSAC by myself, but I never get the exact same list than the one given by the mask. Here are two codes that I wrote. Both use the same Homography matrix <em>cv::Mat H</em>.</p>
<p>Using <strong>findHomography</strong>(), I get a <em>mask</em> as output and I can print the id of the inliers using the following code:</p>
<pre><code>// Somewhere before I did: findHomography(points1, points2, CV_RANSAC, 3, mask)
for (int i = 0; i < nbMatchings; i++)
{
// Select only the inliers (mask entry set to 1)
if ((int)mask.at<uchar>(i, 0) == 1)
{
std::cout << i << ", ";
}
}
std::cout << std::endl;
</code></pre>
<p>Then, supposing I want to compute the inliers myself (without using <em>cv::Mat mask</em>), and by computing the distance between a point and its correspondence using the very same code as in <strong><em>modules/calib3d/src/fundam.cpp</em></strong>:</p>
<pre><code>for (int i = 0; i < nbMatchings; i++)
{
// cv::Mat H is filled by findHomography(points1, points2, CV_RANSAC, 3, mask)
const double* H2 = H.ptr<double>();
float Hf[] = { (float)H2[0], (float)H2[1], (float)H2[2], (float)H2[3], (float)H2[4], (float)H2[5], (float)H2[6], (float)H2[7] };
float ww = 1.f/(Hf[6]*points1[i].x + Hf[7]*points1[i].y + 1.f);
float dx = (Hf[0]*points1[i].x + Hf[1]*points1[i].y + Hf[2])*ww - points2[i].x;
float dy = (Hf[3]*points1[i].x + Hf[4]*points1[i].y + Hf[5])*ww - points2[i].y;
float dist = (float)(dx*dx + dy*dy);
if (dist <= 9) // The threshold used for RANSAC is 3, so the squared distance is 9
{
std::cout << i << ", ";
}
}
std::cout << std::endl;
</code></pre>
<p>Both codes work, and almost give the same results. The point is that in my understanding, it should result exactly in the same list in both codes, and it is obviously not. Usually, the second code outputs up to 10% more inliers than the first code. But some inliers are in the first list and not in the second whilst some are in the second and not in the first.</p>
<p>Does anybody have an idea about this problem? Why is it the case that, using the very same Homography matrix (it is computed only once), I don't get the same inliers twice? </p>
http://answers.opencv.org/question/12295/compute-inliers-for-a-homography/?answer=199397#post-id-199397The size of the Mask matches the size of my keypoints.
Does it mean that when a row in the Mask is 1, that the keypoint1 and keypoint2 at the same row position are the corresponding inliers?Fri, 14 Sep 2018 04:25:18 -0500http://answers.opencv.org/question/12295/compute-inliers-for-a-homography/?answer=199397#post-id-199397Answer by SR for <p>I am trying to compute the inliers of a homography found using RANSAC by myself, but I never get the exact same list than the one given by the mask. Here are two codes that I wrote. Both use the same Homography matrix <em>cv::Mat H</em>.</p>
<p>Using <strong>findHomography</strong>(), I get a <em>mask</em> as output and I can print the id of the inliers using the following code:</p>
<pre><code>// Somewhere before I did: findHomography(points1, points2, CV_RANSAC, 3, mask)
for (int i = 0; i < nbMatchings; i++)
{
// Select only the inliers (mask entry set to 1)
if ((int)mask.at<uchar>(i, 0) == 1)
{
std::cout << i << ", ";
}
}
std::cout << std::endl;
</code></pre>
<p>Then, supposing I want to compute the inliers myself (without using <em>cv::Mat mask</em>), and by computing the distance between a point and its correspondence using the very same code as in <strong><em>modules/calib3d/src/fundam.cpp</em></strong>:</p>
<pre><code>for (int i = 0; i < nbMatchings; i++)
{
// cv::Mat H is filled by findHomography(points1, points2, CV_RANSAC, 3, mask)
const double* H2 = H.ptr<double>();
float Hf[] = { (float)H2[0], (float)H2[1], (float)H2[2], (float)H2[3], (float)H2[4], (float)H2[5], (float)H2[6], (float)H2[7] };
float ww = 1.f/(Hf[6]*points1[i].x + Hf[7]*points1[i].y + 1.f);
float dx = (Hf[0]*points1[i].x + Hf[1]*points1[i].y + Hf[2])*ww - points2[i].x;
float dy = (Hf[3]*points1[i].x + Hf[4]*points1[i].y + Hf[5])*ww - points2[i].y;
float dist = (float)(dx*dx + dy*dy);
if (dist <= 9) // The threshold used for RANSAC is 3, so the squared distance is 9
{
std::cout << i << ", ";
}
}
std::cout << std::endl;
</code></pre>
<p>Both codes work, and almost give the same results. The point is that in my understanding, it should result exactly in the same list in both codes, and it is obviously not. Usually, the second code outputs up to 10% more inliers than the first code. But some inliers are in the first list and not in the second whilst some are in the second and not in the first.</p>
<p>Does anybody have an idea about this problem? Why is it the case that, using the very same Homography matrix (it is computed only once), I don't get the same inliers twice? </p>
http://answers.opencv.org/question/12295/compute-inliers-for-a-homography/?answer=14730#post-id-14730From the docs:
> Regardless of the method, robust or not, the computed homography matrix is refined further (using inliers only in case of a robust method) with the Levenberg-Marquardt method to reduce the re-projection error even more.
Which means: After *H* was obtained by RANSAC, it is further re-fined (=re-estimated) for non-linear optimization of the homography mapping. In this case, least-median of squared is used, I guess.Thu, 06 Jun 2013 01:24:44 -0500http://answers.opencv.org/question/12295/compute-inliers-for-a-homography/?answer=14730#post-id-14730Comment by hayley for <p>From the docs:</p>
<blockquote>
<p>Regardless of the method, robust or not, the computed homography matrix is refined further (using inliers only in case of a robust method) with the Levenberg-Marquardt method to reduce the re-projection error even more.</p>
</blockquote>
<p>Which means: After <em>H</em> was obtained by RANSAC, it is further re-fined (=re-estimated) for non-linear optimization of the homography mapping. In this case, least-median of squared is used, I guess.</p>
http://answers.opencv.org/question/12295/compute-inliers-for-a-homography/?comment=199398#post-id-199398The size of the Mask matches the size of my keypoints.
Does it mean that when a row in the Mask is 1, that the keypoint1 and keypoint2 at the same row position are the corresponding inliers?Fri, 14 Sep 2018 04:26:23 -0500http://answers.opencv.org/question/12295/compute-inliers-for-a-homography/?comment=199398#post-id-199398Answer by nuhnuh for <p>I am trying to compute the inliers of a homography found using RANSAC by myself, but I never get the exact same list than the one given by the mask. Here are two codes that I wrote. Both use the same Homography matrix <em>cv::Mat H</em>.</p>
<p>Using <strong>findHomography</strong>(), I get a <em>mask</em> as output and I can print the id of the inliers using the following code:</p>
<pre><code>// Somewhere before I did: findHomography(points1, points2, CV_RANSAC, 3, mask)
for (int i = 0; i < nbMatchings; i++)
{
// Select only the inliers (mask entry set to 1)
if ((int)mask.at<uchar>(i, 0) == 1)
{
std::cout << i << ", ";
}
}
std::cout << std::endl;
</code></pre>
<p>Then, supposing I want to compute the inliers myself (without using <em>cv::Mat mask</em>), and by computing the distance between a point and its correspondence using the very same code as in <strong><em>modules/calib3d/src/fundam.cpp</em></strong>:</p>
<pre><code>for (int i = 0; i < nbMatchings; i++)
{
// cv::Mat H is filled by findHomography(points1, points2, CV_RANSAC, 3, mask)
const double* H2 = H.ptr<double>();
float Hf[] = { (float)H2[0], (float)H2[1], (float)H2[2], (float)H2[3], (float)H2[4], (float)H2[5], (float)H2[6], (float)H2[7] };
float ww = 1.f/(Hf[6]*points1[i].x + Hf[7]*points1[i].y + 1.f);
float dx = (Hf[0]*points1[i].x + Hf[1]*points1[i].y + Hf[2])*ww - points2[i].x;
float dy = (Hf[3]*points1[i].x + Hf[4]*points1[i].y + Hf[5])*ww - points2[i].y;
float dist = (float)(dx*dx + dy*dy);
if (dist <= 9) // The threshold used for RANSAC is 3, so the squared distance is 9
{
std::cout << i << ", ";
}
}
std::cout << std::endl;
</code></pre>
<p>Both codes work, and almost give the same results. The point is that in my understanding, it should result exactly in the same list in both codes, and it is obviously not. Usually, the second code outputs up to 10% more inliers than the first code. But some inliers are in the first list and not in the second whilst some are in the second and not in the first.</p>
<p>Does anybody have an idea about this problem? Why is it the case that, using the very same Homography matrix (it is computed only once), I don't get the same inliers twice? </p>
http://answers.opencv.org/question/12295/compute-inliers-for-a-homography/?answer=50699#post-id-50699I have the same problem. The masks returned by findHomography seems to be wrong. Anybody knows if it is a bug?Wed, 12 Nov 2014 09:00:53 -0600http://answers.opencv.org/question/12295/compute-inliers-for-a-homography/?answer=50699#post-id-50699