findHomography, getPerspectiveTransform и getAffineTransform

Этот вопрос о функциях OpenCVfindHomography, getPerspectiveTransform & Амп;getAffineTransform

What is the difference between findHomography and getPerspectiveTransform?. My understanding from the documentation is that getPerspectiveTransform computes the transform using 4 correspondences (which is the minimum required to compute a homography/perspective transform) where as findHomography computes the transform even if you provide more than 4 correspondencies (presumably using something like a least squares method?). Is this correct? (In which case the only reason OpenCV still continues to support getPerspectiveTransform should be legacy? )

My next concern is that I want to know if there is an equivalent to findHomography for computing an Affine transformation? i.e. a function which uses a least squares or an equivalent robust method to compute and affine transformation. According to the documentation getAffineTransform takes in only 3 correspondences (which is the min required to compute an affine transform).

Лучший,

 cgat10 янв. 2014 г., 12:48
Может бытьestimateRigidTransform будет соответствовать вашим потребностям.

Ответы на вопрос(4)

measureRigidTransform является эквивалентом getAffineTransform с избыточной дискретизацией. Я не знаю, было ли это в OCV, когда это было впервые опубликовано, но это доступно в 2.4.

Q #1Да, findHomography пытается найти лучшее преобразование между двумя наборами точек. Он использует нечто более умное, чем наименьшие квадраты, называемое RANSAC, которое может отклонять выбросы - если хотя бы 50% + 1 ваших точек данных в порядке, RANSAC сделает все возможное, чтобы найти их и построить надежное преобразование.

У getPerspectiveTransform есть много полезных причин остаться - это база для findHomography, и она полезна во многих ситуациях, когда у вас есть только 4 балла, и вы знаете, что они правильные. FindHomography обычно используется с автоматически определенными наборами точек - вы можете найти многие из них, но с низкой достоверностью. Функция getPerspectiveTransform хороша, когда вы точно знаете 4 угла - например, ручная маркировка или автоматическое определение прямоугольника.

Q #2 Не существует эквивалента для аффинных преобразований. Вы можете использовать findHomography, потому что аффинные преобразования являются подмножеством омографий.

что написал @vasile. Я просто хочу добавить несколько замечаний:

getPerspectiveTransform() а такжеgetAffineTransform() предназначены для работы на4 или же3 точки (соответственно), которые являютсяknown to be correct correspondences, На реальных снимках, сделанных реальной камерой, вы можетеnever получить соответствия, которые точны, а не с автоматической или ручной маркировкой соответствующих точек.

Всегда есть выбросы.Just look at the simple case желания соответствовать кривой через точки (например, взять генеративное уравнение с шумомy1 = f(x) = 3.12x + gauss_noise или жеy2 = g(x) = 0.1x^2 + 3.1x + gauss_noise): гораздо проще найти хорошую квадратичную функцию для оценки точек в обоих случаях, чем хорошую линейную. Квадратик может быть излишним, но в большинстве случаев этого не произойдет (после удаления выбросов), и если вы хотите разместить там прямую линию, лучше быть уверенным, что это правильная модель, иначе вы получите непригодные результаты.

Тем не менее, если выare mightily sure эта аффинная трансформация является правильной, вот предложение:

use findHomography, that has RANSAC incorporated in to the functionality, to get rid of the outliers and get an initial estimate of the image transformation select 3 correct matches-correspondances (that fit with the homography found), or reproject 3 points from the 1st image to the 2nd (using the homography) use those 3 matches (that are as close to correct as you can get) in getAffineTransform() wrap all of that in your own findAffine() if you want - and voila!
 04 авг. 2012 г., 23:54
@penleope, я нашел решение, как найти лучшее (мудрое l2) аффинное преобразование, используя SVD, способом, подобным тому, как вы оцениваете лучшую гомографию.
 11 сент. 2012 г., 14:38
@ Дразик отлично. Опишите это в ответе?
 30 июл. 2012 г., 15:52
Есть ли способ найти лучшего & quot; Аффинного & quot; матрица? Я хочу, чтобы последний ряд омографии был [0, 0, 1].
 31 июл. 2012 г., 10:55
@Drazick «Алгоритм» Я написал, что делает это почти - он использует findHomography, чтобы избавиться от выбросов, и вам не нужно кодировать свой собственный RANSAC, а затем вы можете использовать getAffineTransform () в любых 3 точках, чтобы приблизиться к лучшему аффинно. В качестве альтернативы, вы можете кодировать свой собственный алгоритм RANSAC с помощью getAffineTransform () вместо getPerspectiveTransform () в качестве основной функции.

системы переопределенных уравнений.

Note that in general an Affine transform finds a solution to the over-determined system of linear equations Ax=B by using a pseudo-inverse or a similar technique, so

x = (A At )-1 At B

Более того, это обрабатывается в основной функциональности openCV простым вызовом решения (A, B, X).

Familiarize yourself with the code of Affine transform in opencv/modules/imgproc/src/imgwarp.cpp: it really does just two things:

a. rearranges inputs to create a system Ax=B;

b. then calls solve(A, B, X);

ПРИМЕЧАНИЕ: игнорируйте комментарии функции в коде openCV - они сбивают с толку и не отражают фактического упорядочения элементов в матрицах. Если вы решаете [u, v] & # x2019; = Affine * [x, y, 1], перестановка будет такой:

         x1 y1 1 0  0  1
         0  0  0 x1 y1 1
         x2 y2 1 0  0  1
    A =  0  0  0 x2 y2 1
         x3 y3 1 0  0  1
         0  0  0 x3 y3 1

    X = [Affine11, Affine12, Affine13, Affine21, Affine22, Affine23]’

         u1 v1
    B =  u2 v2
         u3 v3 

Все, что вам нужно сделать, это добавить больше очков. Чтобы заставить Solve (A, B, X) работать в переопределенной системе, добавьте параметр DECOMP_SVD. Чтобы увидеть слайды PowerPoint по теме, используйте этуссылка на сайт, Если вы хотите больше узнать о псевдообращении в контексте компьютерного зрения, лучшим источником будет:Компьютерное зрениесм. главу 15 и приложение С.

Если вы все еще не знаете, как добавить больше очков, посмотрите мой код ниже:

// extension for n points;
cv::Mat getAffineTransformOverdetermined( const Point2f src[], const Point2f dst[], int n )
{
    Mat M(2, 3, CV_64F), X(6, 1, CV_64F, M.data); // output
    double* a = (double*)malloc(12*n*sizeof(double));
    double* b = (double*)malloc(2*n*sizeof(double));
    Mat A(2*n, 6, CV_64F, a), B(2*n, 1, CV_64F, b); // input

    for( int i = 0; i < n; i++ )
    {
        int j = i*12;   // 2 equations (in x, y) with 6 members: skip 12 elements
        int k = i*12+6; // second equation: skip extra 6 elements
        a[j] = a[k+3] = src[i].x;
        a[j+1] = a[k+4] = src[i].y;
        a[j+2] = a[k+5] = 1;
        a[j+3] = a[j+4] = a[j+5] = 0;
        a[k] = a[k+1] = a[k+2] = 0;
        b[i*2] = dst[i].x;
        b[i*2+1] = dst[i].y;
    }

    solve( A, B, X, DECOMP_SVD );
    delete a;
    delete b;
    return M;
}

// call original transform
vector<Point2f> src(3);
vector<Point2f> dst(3);
src[0] = Point2f(0.0, 0.0);src[1] = Point2f(1.0, 0.0);src[2] = Point2f(0.0, 1.0);
dst[0] = Point2f(0.0, 0.0);dst[1] = Point2f(1.0, 0.0);dst[2] = Point2f(0.0, 1.0);
Mat M = getAffineTransform(Mat(src), Mat(dst));
cout<<M<<endl;
// call new transform
src.resize(4); src[3] = Point2f(22, 2);
dst.resize(4); dst[3] = Point2f(22, 2);
Mat M2 = getAffineTransformOverdetermined(src.data(), dst.data(), src.size());
cout<<M2<<endl;

Ваш ответ на вопрос