lindstorm 0 Жалоба Опубликовано December 9, 2012 Ребят,такое дело. Пишу курсовой на тему перспективных преобразований. У меня есть исходный массив CvPoint2D32f srcQuad[4], где хранятся координаты исходного массива и CvPoint2D32f dstQuad[4], где хранятся координаты исходного массива. Затем с помощью функции cvGetPerspectiveTransform(srcQuad, dstQuad, warp_matrix), я получаю матрицу перспективного преобразования CvMat* warp_matrix = cvCreateMat(3,3,CV_32FC1); Это все работает, но мне нужно знать как идет расчет этой матрицы. Нашел формулу на http://opencv.willowgarage.com/documentation/geometric_image_transformations.html, там mapmatrix. Не знаю, как ее считать. Вот еще немного : http://code.google.com/p/javacv/issues/detail?id=82#c2 - здесь показано конечное значение матрицы. Спасибо за любую помощь. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано December 9, 2012 Use the source, Luke! Открываем файл opencv\modules\imgproc\src\imgwarp.cpp, находим там интересующую функцию и читаем : /* Calculates coefficients of perspective transformation * which maps (xi,yi) to (ui,vi), (i=1,2,3,4): * * c00*xi + c01*yi + c02 * ui = --------------------- * c20*xi + c21*yi + c22 * * c10*xi + c11*yi + c12 * vi = --------------------- * c20*xi + c21*yi + c22 * * Coefficients are calculated by solving linear system: * / x0 y0 1 0 0 0 -x0*u0 -y0*u0 \ /c00\ /u0\ * | x1 y1 1 0 0 0 -x1*u1 -y1*u1 | |c01| |u1| * | x2 y2 1 0 0 0 -x2*u2 -y2*u2 | |c02| |u2| * | x3 y3 1 0 0 0 -x3*u3 -y3*u3 |.|c10|=|u3|, * | 0 0 0 x0 y0 1 -x0*v0 -y0*v0 | |c11| |v0| * | 0 0 0 x1 y1 1 -x1*v1 -y1*v1 | |c12| |v1| * | 0 0 0 x2 y2 1 -x2*v2 -y2*v2 | |c20| |v2| * \ 0 0 0 x3 y3 1 -x3*v3 -y3*v3 / \c21/ \v3/ * * where: * cij - matrix coefficients, c22 = 1 */ cv::Mat cv::getPerspectiveTransform( const Point2f src[], const Point2f dst[] ) { Mat M(3, 3, CV_64F), X(8, 1, CV_64F, M.data); double a[8][8], b[8]; Mat A(8, 8, CV_64F, a), B(8, 1, CV_64F, B ) ; for( int i = 0; i < 4; ++i ) { a[i][0] = a[i+4][3] = src[i].x; a[i][1] = a[i+4][4] = src[i].y; a[i][2] = a[i+4][5] = 1; a[i][3] = a[i][4] = a[i][5] = a[i+4][0] = a[i+4][1] = a[i+4][2] = 0; a[i][6] = -src[i].x*dst[i].x; a[i][7] = -src[i].y*dst[i].x; a[i+4][6] = -src[i].x*dst[i].y; a[i+4][7] = -src[i].y*dst[i].y; b[i] = dst[i].x; b[i+4] = dst[i].y; } solve( A, B, X, DECOMP_SVD ); ((double*)M.data)[8] = 1.; return M; } [/code] Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано December 9, 2012 на форуме обсуждалось и прямое и обратное преобразование и откуда там вылезает линейная система. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
lindstorm 0 Жалоба Опубликовано December 10, 2012 Сделал по примеру. Только делаю в билдере и поэтому функция cvSolve малость другая Но почему-то массив coeff, в котором должны быть коэффициенты матрицы заполняется нулями. CvMat* warp_matrix = cvCreateMat(3,3,CV_64FC1); double a[8][8], b[8]; double coeff[8]; CvMat A = cvMat( 8, 8, CV_64FC1, a) ; CvMat B = cvMat( 8, 1, CV_64FC1, b ); CvMat X = cvMat( 8, 1, CV_64FC1, coeff ); for(int i =0; i < 4;++i) { a[0] = a[i+4][3] = srcQuad.x; a[1] = a[i+4][5] = srcQuad.y; a[2] = a[i+4][5] = 1; a[3] = a[4] = a[5] = a[i + 4][0] = a[i+4][1] = a[i+4][2] = 0; a[6] = -srcQuad.x * dstQuad.x; a[7] = -srcQuad.y * dstQuad.x; a[i+4][6] = -srcQuad.x * dstQuad.y; a[i+4][7] = -srcQuad.y * dstQuad.y; b = dstQuad.x; b[i+4] = dstQuad.y; } cvSolve( &A, &B, &X ); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано December 10, 2012 a[1] = a[i+4][5] = srcQuad.y; опечатка Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
lindstorm 0 Жалоба Опубликовано December 10, 2012 Спасибо! Все получилось! Во-первых опечатка, во вторых матрицу warp_matrix надо создавать типа CV_32FC1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано December 10, 2012 по поводу матрицы не уверен, CV_32FC1 это float, а массив coeff имеет тип double, которому соответствует CV_64FC1. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах