What happens if I give more resources in a RigidTransform or getAffineTransform evaluation?

I use a RigidTransform score with about two vectors of 100 points each and works FINE. But somehow getAffineTransform is not working.

I know that findHomography finds the best matrix using RANSAC, and getPerspectiveTransform requires only 4 points.

My question is, what happens if I give more resources in a RigidTransform or getAffineTransform evaluation?

Is it only 4 points from the input matrix? Or do some RANSAC?

+5
source share
1 answer

The above functions can be divided into 3 different types:

Type 1: getAffineTransform and getPerspectiveTransform. Given 3 points on one plane and 3 points of correspondence on another, you can calculate the affine transformation between these planes. And, given 4 points, you can find a promising transformation. This is all that getAffineTransform and getPerspectiveTransform can do: they need 3 and 4 pairs of points, nothing more, and calculate the corresponding transformation. The one and only.

Type 2: RigidTransform Evaluation. If you cannot get your glasses with absolute accuracy (which usually happens when you get them from an image), you need more than three pairs of points to reduce the error. The more fun (i.e. better accuracy). There is more than one way to identify the error you want to reduce, and what approach you use to find the minimum error. evaluating a RigidTransform minimizes the least-square error (I think the most popular definition of error). He does this by solving a system of equations. If you give 3 points exactly, the result will of course be the same as the result of getAffineTransform. You may ask why we need to getAffineTransform in OpenCV if the RigidTransform evaluation can do its job. Alas, this is not the only redundancy in OpenCV.

Type 3: findHomography. This one is more advanced. Not only can it deal with errors at point locations, but it can also deal with the existence of outliers. If there are incorrect matches between the points, then using them to estimate the minimum square error will lead to very poor accuracy. It can use RANSAC or LMeDs to check for possible matches and eliminate these outliers. It works like several iterations of a RigidTransform score: find the smallest square match for the different subsets of points. If you know that there are no deviations, you can set the "method" argument to 0, and it will work the same as the RigidTransform score, trying to minimize the smallest square error created from matching all points.

Change Thanks to Mika for his comment.

I think my memory plays on me. I remembered that the RigidTransform estimate was implemented through the equation system in OpenCV, but now I checked it and saw that Mika was right. It uses some hard-coded RANSAC in it ... Sorry for your misuse.

For those who are still interested in solving closed forms instead of RANSAC, here it is:

// find affine transformation between two pointsets (use least square matching) static bool computeAffine(const vector<Point2d> &srcPoints, const vector<Point2d> &dstPoints, Mat &transf) { // sanity check if ((srcPoints.size() < 3) || (srcPoints.size() != dstPoints.size())) return false; // container for output transf.create(2, 3, CV_64F); // fill the matrices const int n = (int)srcPoints.size(), m = 3; Mat A(n,m,CV_64F), xc(n,1,CV_64F), yc(n,1,CV_64F); for(int i=0; i<n; i++) { double x = srcPoints[i].x, y = srcPoints[i].y; double rowI[m] = {x, y, 1}; Mat(1,m,CV_64F,rowI).copyTo(A.row(i)); xc.at<double>(i,0) = dstPoints[i].x; yc.at<double>(i,0) = dstPoints[i].y; } // solve linear equations (for x and for y) Mat aTa, resX, resY; mulTransposed(A, aTa, true); solve(aTa, At()*xc, resX, DECOMP_CHOLESKY); solve(aTa, At()*yc, resY, DECOMP_CHOLESKY); // store result memcpy(transf.ptr<double>(0), resX.data, m*sizeof(double)); memcpy(transf.ptr<double>(1), resY.data, m*sizeof(double)); return true; } 
+16
source

Source: https://habr.com/ru/post/1200642/


All Articles