# Residual error from fundamental matrix [closed]

Hi guys,

as in the previous topics I made I'm still working on self calibration stuff. I'm generating the data for the evaluation but I end out with some strange error computing the residual error as defined here slide 31. But maybe I'm using the wrong function to compute the norm. The resulting residual error is absurd, while the epipolar equation x'Fx=0 give to me a residual of 0.25 so I suppose is almost perfect.

I've points correspondences for image L and R and the fundamental matrix. Actually I'm doing in this way, I don't care that it isn't efficient since is not important, is just for data generation.

 for(int i=0; i<maskInliers.rows; i++)
{
{
inliersL.push_back(featuresL.at(i));
inliersR.push_back(featuresR.at(i));

cv::Mat temp_point_1 = cv::Mat(3,1,CV_64F);
temp_point_1.at<double>(0,0) = featuresL.at(i).x;
temp_point_1.at<double>(1,0) = featuresL.at(i).y;
temp_point_1.at<double>(2,0) = 1;

cv::Mat temp_point_2 = cv::Mat(3,1,CV_64F);
temp_point_2.at<double>(0,0) = featuresR.at(i).x;
temp_point_2.at<double>(1,0) = featuresR.at(i).y;
temp_point_2.at<double>(2,0) = 1;

/*******************************
* COMPUTING THE F RESIDUALS
*******************************/
//Epipolar equation x'Fx=0
cv::Mat tempResF = temp_point_2.t()*fundamentalMat*temp_point_1;
residualF += fabs(tempResF.at<double>(0,0));

//Residual error
double resError = cv::norm(temp_point_2-(fundamentalMat*temp_point_1)) +
cv::norm(temp_point_1-(fundamentalMat.t()*temp_point_2));
residualF_error += resError;
}
}


I would like to find the residual error, is there any built in function to do that? I've looked on the documentation but I've not find it.

EDIT: the result I'm getting are the following:

Residual of F 0.250138
Mean residual of F 0.0039084
F RESIDUAL ERROR: 65237.2


where:

• Residual of F is computed using the epipolar geometry x'Fx=0
• mean error is the previous value divided by the number of inliers used for estimating the fundamental matrix
• The last one (F RESIDUAL ERROR) is the one that is wrong and that I'm asking about
edit retag reopen merge delete

### Closed for the following reason the question is answered, right answer was accepted by HYPEREGO close date 2020-05-11 07:52:01.216318

1

That is OpenCV2 not OpenCV 3. The book is too old for you.

( 2020-03-02 12:41:37 -0500 )edit

Which book are you talking about? I don't get the point. I just linked a presentation for reference, the formula I suppose is still the same :-D I edited the question adding some result that I got.

( 2020-03-02 13:00:56 -0500 )edit
1

You don't understand about pdf. It is showing on front cover dating back to 2010.. It it marking on OpenCV II not OpenCV III. The code is not same as OpenCV 3 and OpenCV 4. OpenCV 2 will worked on OpenCV4(same code), but not OpenCV 3

( 2020-03-02 13:42:37 -0500 )edit
1

You haven't stating which version.

( 2020-03-02 13:49:39 -0500 )edit

I don't get this code from the pdf, it is mine. I just linked the pdf as a reference for the residual error formula (slide 31), you can forget the PDF, it doesn't matter at all in my work, neither I used it. The same formula can be found on HZ book for example. The point of my question is that I don't get the correct results (using the attached code) despite the residuals based on the fundamental matrix equation are good. By the way, I'm using OpenCV 3.

( 2020-03-02 13:55:59 -0500 )edit
1

Ok! Are you looping? This can't be right temp_point_1.at<double>(0,0) = featuresL.at(i).x; If you're literatior this should be like this temp_point_1.at<double>(0, i) = featuresL.at(i).x;

( 2020-03-02 14:33:19 -0500 )edit
1

Mat A(3,4,CV_64F); //3xN, P1
Mat B(3,4,CV_64F); //3xN, P2
//B = H*A  (P2 = h(P1))

for(int i=0; i< 4; ++i)
{
A.at< double>(0,i) = P1[i].x;
A.at< double>(1,i) = P1[i].y;
A.at< double>(2,i) = 1;

B.at< double>(0,i) = P2[i].x;
B.at< double>(1,i) = P2[i].y;
B.at< double>(2,i) = 1;
}

( 2020-03-02 14:38:32 -0500 )edit

Yes, I'm looping. Basically I loop thru the features arrays, and if the point is an inlier (based on the mask value from findFundamentalMat) then I put the point of L and R in a temporary matrix, temp_point_1 and temp_point_2 and then from that I compute the residual for each point. What does it change if the matrix have 1 or let's say, N column? You suggest to me to put every point in a matrix that at the end should be 3xN with N the number of inliers. Then how I can find the residual error? B=H*A so basically is going to be B=F*A? And as a result F.t()*B = A, and here I'm in (and this is what I'm actually doing), but how to compute the residual error? To be clearer I'm going to add the entire code ...(more)

( 2020-03-02 14:58:02 -0500 )edit

OK, I managed to get the right reprojection error using the code inside findFundamentalMat as here and I changed part of the code that I posted previously. But I don't get why for every pairs of corresponding points, I get a quite big (14.61) mean residual value applying x'Fx=0. That's crappy. The coordinates should be normalized?

( 2020-04-24 05:54:04 -0500 )edit

Sort by » oldest newest most voted

I finally solved this problem using the code from findFundamentalMat as suggested by @Eduardo in his question and answer.

I used the computeError function (link to the code).

more

Official site

GitHub

Wiki

Documentation