若该文为原创文章,未经容许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:http://www.javashuo.com/article/p-wxwjppoc-mo.html
本文章博客地址:http://www.javashuo.com/article/p-aiytbdck-bs.html
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么本身研究函数
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)ui
上一篇:《OpenCV开发笔记(四十五):红胖子8分钟带你深刻了解重映射(图文并茂+浅显易懂+程序源码)》.net
下一篇:《OpenCV开发笔记(四十七):红胖子8分钟带你深刻了解直方图(图文并茂+浅显易懂+程序源码)》3d
红胖子来也!!!code
图像处理中的仿射,仿射其实原理与重映射相似,其能够理解为更高级的重映射变换。orm
《OpenCV开发笔记(八):OpenCV经常使用操做之计时、缩放、旋转、镜像》blog
该文章中,也一样实现了部分简单重映射效果,使用的四个函数:ip
《OpenCV开发笔记(四十五):红胖子8分钟带你深刻了解重映射(图文并茂+浅显易懂+程序源码)》开发
仿射变换(仿射映射)是指在几何中,一个响亮空间进行一次线性变换并接上一个平移,变换为另外一个向量空间的过程。get
一个任意的仿射都能表示为乘以一个矩阵再加上一个向量(平移)的形式(注:重映射能够理解为是一种简单的仿射变换)。
仿射是用矩阵表示变换的关系,一般使用的是2 x 3的矩阵来表示仿射变换。
整个映射关系为:
dst = src * A + B
其中:
A为线性变换矩阵,B为向量加矩阵;
对应的每一个像素的变换关系,则是:
dst(x,y) = src(x,y) * A + B
下面上图解释仿射(三个点就是函数提供计算仿射矩阵须要咱们输入的点):
仿射变换的原理与重映射不一样,重映射是直接对像素点的序号进行映射,能够作些拉长,特色像素着重等等(如哈哈镜),而仿射变换是对原矩阵的标准变换,有适合各自的场景。
void warpAffine( InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar());
Mat getAffineTransform( InputArray src, InputArray dst );
Mat getRotationMatrix2D( Point2f center, double angle, double scale );
void OpenCVManager::testAffineMap() { QString fileName1 = "E:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.jpg"; cv::Mat srcMat = cv::imread(fileName1.toStdString()); cv::Mat dstMat; int width = 400; int height = 300; cv::resize(srcMat, srcMat, cv::Size(width, height)); cv::String windowName = _windowTitle.toStdString(); cvui::init(windowName); cv::Mat windowMat = cv::Mat(cv::Size(srcMat.cols * 2, srcMat.rows * 4), srcMat.type()); while(true) { windowMat = cv::Scalar(0, 0, 0); cv::Mat mat = windowMat(cv::Range(srcMat.rows * 0, srcMat.rows * 1), cv::Range(srcMat.cols * 0, srcMat.cols * 1)); cv::addWeighted(mat, 0.0f, srcMat, 1.0f, 0.0f, mat); // 第一种旋转180度 { cv::Mat M = cv::getRotationMatrix2D(cv::Point(srcMat.cols / 2, srcMat.rows / 2), 180.0f, 1.0f); dstMat = srcMat.clone(); dstMat = cv::Scalar(0, 0, 0); cv::warpAffine(srcMat, dstMat, M, cv::Size(srcMat.cols, srcMat.rows)); mat = windowMat(cv::Range(srcMat.rows * 0, srcMat.rows * 1), cv::Range(srcMat.cols * 1, srcMat.cols * 2)); cv::addWeighted(mat, 0.0f, dstMat, 1.0f, 0.0f, mat); } // 第二种旋转45度,缩小1/2 { cv::Mat M = cv::getRotationMatrix2D(cv::Point(srcMat.cols / 2, srcMat.rows / 2), 45.0f, 0.5f); dstMat = srcMat.clone(); dstMat = cv::Scalar(0, 0, 0); cv::warpAffine(srcMat, dstMat, M, cv::Size(srcMat.cols, srcMat.rows)); mat = windowMat(cv::Range(srcMat.rows * 1, srcMat.rows * 2), cv::Range(srcMat.cols * 0, srcMat.cols * 1)); cv::addWeighted(mat, 0.0f, dstMat, 1.0f, 0.0f, mat); } // 第三种旋转315度,缩小1/2 { cv::Mat M = cv::getRotationMatrix2D(cv::Point(srcMat.cols / 2, srcMat.rows / 2), 315.0f, 0.5f); dstMat = srcMat.clone(); dstMat = cv::Scalar(0, 0, 0); cv::warpAffine(srcMat, dstMat, M, cv::Size(srcMat.cols, srcMat.rows)); mat = windowMat(cv::Range(srcMat.rows * 1, srcMat.rows * 2), cv::Range(srcMat.cols * 1, srcMat.cols * 2)); cv::addWeighted(mat, 0.0f, dstMat, 1.0f, 0.0f, mat); } // 第四种旋转135度,缩小1/2 { cv::Mat M = cv::getRotationMatrix2D(cv::Point(srcMat.cols / 2, srcMat.rows / 2), 135.0f, 0.5f); dstMat = srcMat.clone(); dstMat = cv::Scalar(0, 0, 0); cv::warpAffine(srcMat, dstMat, M, cv::Size(srcMat.cols, srcMat.rows)); mat = windowMat(cv::Range(srcMat.rows * 2, srcMat.rows * 3), cv::Range(srcMat.cols * 0, srcMat.cols * 1)); cv::addWeighted(mat, 0.0f, dstMat, 1.0f, 0.0f, mat); } // 第五种旋转225度,缩小1/2 { cv::Mat M = cv::getRotationMatrix2D(cv::Point(srcMat.cols / 2, srcMat.rows / 2), 225.0f, 0.5f); dstMat = srcMat.clone(); dstMat = cv::Scalar(0, 0, 0); cv::warpAffine(srcMat, dstMat, M, cv::Size(srcMat.cols, srcMat.rows)); mat = windowMat(cv::Range(srcMat.rows * 2, srcMat.rows * 3), cv::Range(srcMat.cols * 1, srcMat.cols * 2)); cv::addWeighted(mat, 0.0f, dstMat, 1.0f, 0.0f, mat); } // 第六种使用三角点进行仿射变换,沿着对角线翻转 { cv::Point2f srcTraingle[3]; cv::Point2f dstTraingle[3]; srcTraingle[0] = cv::Point2f(0, 0); srcTraingle[1] = cv::Point2f(srcMat.cols - 1, 0); srcTraingle[2] = cv::Point2f(0, srcMat.rows - 1); dstTraingle[0] = cv::Point2f(0, 0); dstTraingle[1] = cv::Point2f(0, srcMat.rows - 1); dstTraingle[2] = cv::Point2f(srcMat.cols - 1, 0); cv::Mat M = cv::getAffineTransform(srcTraingle, dstTraingle); dstMat = srcMat.clone(); dstMat = cv::Scalar(0, 0, 0); cv::warpAffine(srcMat, dstMat, M, cv::Size(srcMat.cols, srcMat.rows)); mat = windowMat(cv::Range(srcMat.rows * 3, srcMat.rows * 4), cv::Range(srcMat.cols * 0, srcMat.cols * 1)); cv::addWeighted(mat, 0.0f, dstMat, 1.0f, 0.0f, mat); } // 第七种使用三角点进行仿射变换 { cv::Point2f srcTraingle[3]; cv::Point2f dstTraingle[3]; srcTraingle[0] = cv::Point2f(0, 0); srcTraingle[1] = cv::Point2f(srcMat.cols - 1, 0); srcTraingle[2] = cv::Point2f(0, srcMat.rows - 1); dstTraingle[0] = cv::Point2f(srcMat.cols / 4, srcMat.rows / 4); dstTraingle[1] = cv::Point2f(srcMat.cols / 4 * 3, srcMat.rows / 4 ); dstTraingle[2] = cv::Point2f(srcMat.cols / 2, srcMat.rows - 1); cv::Mat M = cv::getAffineTransform(srcTraingle, dstTraingle); dstMat = srcMat.clone(); dstMat = cv::Scalar(0, 0, 0); cv::warpAffine(srcMat, dstMat, M, cv::Size(srcMat.cols, srcMat.rows)); mat = windowMat(cv::Range(srcMat.rows * 3, srcMat.rows * 4), cv::Range(srcMat.cols * 1, srcMat.cols * 2)); cv::addWeighted(mat, 0.0f, dstMat, 1.0f, 0.0f, mat); } // 更新 cvui::update(); // 显示 cv::imshow(windowName, windowMat); // esc键退出 if(cv::waitKey(25) == 27) { break; } } }
对应版本号v1.41.0
上一篇:《OpenCV开发笔记(四十五):红胖子8分钟带你深刻了解重映射(图文并茂+浅显易懂+程序源码)》
下一篇:《OpenCV开发笔记(四十七):红胖子8分钟带你深刻了解直方图(图文并茂+浅显易懂+程序源码)》
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:http://www.javashuo.com/article/p-wxwjppoc-mo.html
本文章博客地址:http://www.javashuo.com/article/p-aiytbdck-bs.html