Использование оценкиRigidTransform вместо findHomography

Пример по ссылке ниже использует findHomography чтобы получить преобразование между двумя наборами точек. Я хочу ограничить степени свободы, используемые в преобразовании, поэтому хочу заменить findHomography с estimateRigidTransform,

http://docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html#feature-homography

Ниже я использую estimateRigidTransform чтобы получить преобразование между объектом и точками сцены. objPoints а также scePoints представлены vector <Point2f>,

Mat H = estimateRigidTransform(objPoints, scePoints, false);

Следуя методике, использованной в приведенном выше руководстве, я хочу преобразовать значения углов, используя преобразование H, Учебник использует perspectiveTransform с матрицей 3×3, возвращенной findHomography, С жестким преобразованием он возвращает только матрицу 2×3, поэтому этот метод не может быть использован.

Как бы я преобразовал значения углов, представленных в виде vector <Point2f> с этой матрицей 2×3. Я просто хочу выполнять те же функции, что и в руководстве, но с меньшими степенями свободы для преобразования. Я смотрел на другие методы, такие как warpAffine а также getPerspectiveTransform как хорошо, но пока не нашел решения.

РЕДАКТИРОВАТЬ:

Я попробовал предложение от Дэвида Нилосека. Ниже я добавляю дополнительную строку в матрицу.

Mat row = (Mat_<double>(1,3) << 0, 0, 1);
H.push_back(row);

Однако это выдает эту ошибку при использовании перспективы.

OpenCV Error: Assertion failed (mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0)) in create, file /Users/cgray/Downloads/opencv-2.4.6/modules/core/src/matrix.cpp, line 1486
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /Users/cgray/Downloads/opencv-2.4.6/modules/core/src/matrix.cpp:1486: error: (-215) mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0) in function create

ChronoTrigger предложил использовать warpAffine, Я звоню warpAffine Метод ниже, размер 1 х 5 является размером objCorners а также sceCorners,

warpAffine(objCorners, sceCorners, H, Size(1,4));

Это дает ошибку ниже, которая указывает на неправильный тип. objCorners а также sceCorners являются vector <Point2f> представляя 4 угла. я думал warpAffine примет Mat изображения, которые могут объяснить ошибку.

OpenCV Error: Assertion failed ((M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 2 && M0.cols == 3) in warpAffine, file /Users/cgray/Downloads/opencv-2.4.6/modules/imgproc/src/imgwarp.cpp, line 3280

4

Решение

Я делал это в прошлом:

cv::Mat R = cv::estimateRigidTransform(p1,p2,false);

if(R.cols == 0)
{
continue;
}

cv::Mat H = cv::Mat(3,3,R.type());
H.at<double>(0,0) = R.at<double>(0,0);
H.at<double>(0,1) = R.at<double>(0,1);
H.at<double>(0,2) = R.at<double>(0,2);

H.at<double>(1,0) = R.at<double>(1,0);
H.at<double>(1,1) = R.at<double>(1,1);
H.at<double>(1,2) = R.at<double>(1,2);

H.at<double>(2,0) = 0.0;
H.at<double>(2,1) = 0.0;
H.at<double>(2,2) = 1.0;cv::Mat warped;
cv::warpPerspective(img1,warped,H,img1.size());

то же самое, что предложил Дэвид Нилосек: добавить строку 0 0 1 в конце матрицы

этот код деформирует ИЗОБРАЖЕНИЯ с жестким преобразованием.

Если вы хотите деформировать / трансформировать точки, вы должны использовать perspectiveTransform функция с матрицей 3х3 ( http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=perspectivetransform#perspectivetransform )

учебник здесь:

http://docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html

или вы можете сделать это вручную, зацикливая свой вектор и

cv::Point2f result;
result.x = point.x * R.at<double>(0,0) + point.y * R.at<double>(0,1) + R.at<double>(0,2);
result.y = point.x * R.at<double>(1,0) + point.y * R.at<double>(1,1) + R.at<double>(1,2);

надеюсь, это поможет.

примечание: не проверял ручной код, но должен работать. Там нет необходимости в преобразовании PerspectiveTransform!

редактировать: это полный (проверенный) код:

// points
std::vector<cv::Point2f> p1;
p1.push_back(cv::Point2f(0,0));
p1.push_back(cv::Point2f(1,0));
p1.push_back(cv::Point2f(0,1));

// simple translation from p1 for testing:
std::vector<cv::Point2f> p2;
p2.push_back(cv::Point2f(1,1));
p2.push_back(cv::Point2f(2,1));
p2.push_back(cv::Point2f(1,2));

cv::Mat R = cv::estimateRigidTransform(p1,p2,false);

// extend rigid transformation to use perspectiveTransform:
cv::Mat H = cv::Mat(3,3,R.type());
H.at<double>(0,0) = R.at<double>(0,0);
H.at<double>(0,1) = R.at<double>(0,1);
H.at<double>(0,2) = R.at<double>(0,2);

H.at<double>(1,0) = R.at<double>(1,0);
H.at<double>(1,1) = R.at<double>(1,1);
H.at<double>(1,2) = R.at<double>(1,2);

H.at<double>(2,0) = 0.0;
H.at<double>(2,1) = 0.0;
H.at<double>(2,2) = 1.0;

// compute perspectiveTransform on p1
std::vector<cv::Point2f> result;
cv::perspectiveTransform(p1,result,H);

for(unsigned int i=0; i<result.size(); ++i)
std::cout << result[i] << std::endl;

который дает результат, как и ожидалось:

[1, 1]
[2, 1]
[1, 2]
4

Другие решения

Аффинные преобразования (результат cv::estimateRigidTransform) применяются к изображению с помощью функции cv::warpAffine,

2

Гомографическая форма 3×3 жесткого преобразования:

 a1 a2 b1
-a2 a3 b2
0  0  1

Так что при использовании estimateRigidTransform Вы можете добавить [0 0 1] в качестве третьей строки, если вы хотите матрицу 3×3.

2
По вопросам рекламы [email protected]