100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 透视变换原理推导及矩阵求解

透视变换原理推导及矩阵求解

时间:2018-08-22 00:54:34

相关推荐

透视变换原理推导及矩阵求解

原理,推导过程

代码实现

#include <iostream>#include <opencv2/highgui.hpp>#include <opencv2/imgproc.hpp>#include <Eigen/dense>/* 从原图中选取4个点,在目标图像中找出对应的想要映射到的4个点,根据这4对点列出8个方程求解出透视变换的8个参数(3点不共线) */int main(){/* 求解源图像到目标图像的透视变换矩阵,据源图上四个点src_pt到目标图像上的四个点dst_pt进行求解src_pt[0] --> dst_pt[0]src_pt[1] --> dst_pt[1]src_pt[2] --> dst_pt[2]src_pt[3] --> dst_pt[3] */cv::Point2f src_pt[] ={cv::Point2f(390,0),cv::Point2f(1250,0),cv::Point2f(1250,840),cv::Point2f(390, 840) };cv::Point2f dst_pt[] ={cv::Point2f(280,220),cv::Point2f(400,220),cv::Point2f(450,430),cv::Point2f(310, 410) };/* 方法一:根据透视变换的原理实现的透视矩阵的求解 */Eigen::MatrixXd m(8, 8); // 线性方程组的系数for (int i = 0; i < m.rows(); ++i){for (int j = 0; j < m.cols(); ++j){if (i % 2 == 0) // 偶数行{if (j <= 2){if (0 == j){m(i, j) = src_pt[i / 2].x;}else if (1 == j){m(i, j) = src_pt[i / 2].y;}else{m(i, j) = 1;}}else if (j >=3 && j <= 5){m(i, j) = 0;}else{if (6 == j){m(i, j) = -src_pt[i / 2].x * dst_pt[i / 2].x;}else // 7 == j{m(i, j) = -src_pt[i / 2].y * dst_pt[i / 2].x;}}}else // 奇数行{if (j <= 2){m(i, j) = 0;}else if (j >= 3 && j <= 5){if (3 == j){m(i, j) = src_pt[i / 2].x;}else if (4 == j){m(i, j) = src_pt[i / 2].y;}else{m(i, j) = 1;}}else{if (6 == j){m(i, j) = -src_pt[i / 2].x * dst_pt[i / 2].y;}else // 7 == j{m(i, j) = -src_pt[i / 2].y * dst_pt[i / 2].y;}}}}}std::cout << m << std::endl;Eigen::MatrixXd dst_matrix(8, 1);for (int i = 0; i < dst_matrix.rows(); ++i){if (i % 2 == 0){dst_matrix(i, 0) = dst_pt[i / 2].x;}else{dst_matrix(i, 0) = dst_pt[i / 2].y;}}std::cout << "-----------------------------------" << std::endl;Eigen::MatrixXd perspective_matrix = m.inverse() * dst_matrix; // 透视变换矩阵的8个参数std::cout << perspective_matrix << "\n-->" << std::endl;Eigen::MatrixXd ptmatrix_eigen(9, 1);int i = 0;for (; i < perspective_matrix.rows(); ++i){ptmatrix_eigen(i, 0) = perspective_matrix(i, 0);}ptmatrix_eigen(i) = 1;std::cout << ptmatrix_eigen << std::endl;std::cout << "-----------------------------------" << std::endl;/* 方法二:直接调用OpenCV的API实现的透视矩阵的求解 */cv::Mat ptmatrix_cv = cv::getPerspectiveTransform(src_pt, dst_pt);std::cout << ptmatrix_cv << std::endl;/* 比较ptmatrix_eigen和ptmatrix_cv,可知求解结果一致 */// ... 省略比较过程,直接看打印结果/* 直接调用OpenCV的透视变换API进行图像变换,并可视化透视变换效果 */cv::Mat carton = cv::imread("../data/carton2.jpg");cv::Mat beauty = cv::imread("../data/beauty1.jpg");cv::Mat tmp;cv::warpPerspective(beauty, tmp, ptmatrix_cv, cv::Size(carton.cols, carton.rows));cv::Rect rect(280, 220, 170, 230);tmp(rect).copyTo(carton(rect));cv::imshow("perspective_carton", carton);cv::waitKey(0);return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。