OpenCV2.4.13中warpAffine函数理解,旋转,仿射变换,缩放,保持完整图片
来源:互联网 发布:上海数据港官网 编辑:程序博客网 时间:2024/05/14 23:46
本文借鉴了这里以及这里的内容。
问题:为什么写这个东西?
答:在进行模板匹配的时候,发现一个问题,对于直接从图片中抠出的模板,匹配效果较好,但是当模板发生形变的时候,效果就不理想了。
在对模板进行形变处理的时候,发现利用 warpAffine得到的结果并不是想要的结果。
因此,就对这个问题进行了搜索。
Mat img = imread(IMG_PATH); if (img.empty()) cerr<<"can not load image"<<endl; // 定义仿射变换的,中心,角度,尺度 center = Point2f(img.cols/2.0, img.rows/2.0); degree = 60; scale = 1; // 获取变换矩阵 rot = getRotationMatrix2D(center,degree,scale); rimg; warpAffine(img,rimg,rot,img.size()); imshow("img",img); imshow("rimg",rimg);
原图
直接利用warpAffine得到的结果:
问题:这个并不是想要的结果,怎么办呢?
答:看看是不是函数用错了呢?
在程序中有这样一句
getRotationMatrix2D(center,degree,scale);
那么这个“getRotationMatrix2D”是什么鬼呢?
查看手册得到:
问题:这里的公式是怎么来的呢?
答:这里给出了解释,但是好像不是很细诶,为什么可以得到那些结果呢?
- 自己推导了一下:
- 将图中的第 5 步得到的结果与手册中的公式对照,恩,是一样的。
问题:是不是这个函数:warpAffine 用错了呢?
答:搜索手册得到:
注意下面这段话:
问题:这句话什么意思呢?
答:默认输入的变换矩阵 M 是 “逆变换”矩阵。
问题:为什么呢?
答:这个要看这一页手册的最上端:
- 这段话的意思也就是说,在OpenCV中实现的时候,变换之后图像的点dst(x,y),是根据“逆变换”,找到在原图像中是哪一个点src(fx,fy)与之对应的。
问题:说了这么多,到底是什么意思呢?
答:别急,下面给出结论。
通过上面的分析,说明了为什么利用warpAffine 函数得到的 图像不完全了。
比如,以(0,0)为中心,逆时针旋转 45度,尺度缩放为 1.
我们看两个具体的点。
由于我们是利用“逆变换”找到原图中哪些点映射成为变换之后的点。因此,dst 只包含了一部分 “变换之后的图像”中的像素,其他的地方,都默认为黑色了。
与上面对应的具体的一个例子:
// 定义仿射变换的,中心,角度,尺度 Point2f center; center = Point2f(0,0); double degree = 45; double scale = 1; // 旋转 45 度的例子 Mat rot = getRotationMatrix2D(center,degree,scale); Mat rimg; warpAffine(img,rimg,rot,img.size()); imshow("45",rimg);
问题:将dst的大小变大一些可以显示出全部变换之后的图像么?
答:不能,不信你试试。
问题:那怎么办呢?
答:先给出代码:代码参考了这里的内容。
// 获取变换矩阵 rot = getRotationMatrix2D(center,degree,scale); rimg; warpAffine(img,rimg,rot,img.size()); imshow("img",img); imshow("rimg",rimg); // 获取变换之后的 区域,这个很重要,不然的话,变换之后的图像显示不全 Rect bbox; bbox = RotatedRect(center,Size(scale*img.cols,scale*img.rows),degree).boundingRect(); // 对变换矩阵的最后一列做修改,重新定义变换的 中心 rot.at<double>(0,2) += bbox.width/2 - center.x; rot.at<double>(1,2) += bbox.height/2 - center.y; Mat dst; warpAffine(img,dst,rot, bbox.size()); imshow("dst",dst);
得到的结果:
**问题:代码中 bbox = RotatedRect(center,Size(scale*img.cols,scale*img.rows),degree).boundingRect();
是什么鬼?**
答:这一句就是获取,展示变换之后图像所需图片的大小。
手册中 RotatedRect 给出的一个例子很好的展示了这个意思:
图中蓝色是利用 RotatedRect 得到的 Rect 的区域,绿色是变换之后的图像。
问题:最后boundingRect(); 表示什么意思呢?
答:直观理解相当于对这个区域“向大取整”。
**问题:代码中 rot.at<double>(0,2) += bbox.width/2 - center.x;
rot.at<double>(1,2) += bbox.height/2 - center.y;
是什么意思呢?**
答:还记得前面最后推导出来的公式么:
这两行代码的意思就相当于:
直观的意义就是:变换前的中心(x0,y0),在变换之后在(bw/2,bh/2)。也就是 dst 的中心。
**问题:为什么你代码中,将变换前的中心设置为center = Point2f(img.cols/2.0, img.rows/2.0);
?
设置为其他的点不可以么?**
答:设置为其他的点,确实不可以,还是会出现显示不全的问题。我们关心的是放射变换之后的全图是生么样的,与变换前的中心在哪里没有关系,只是相当于将变换之后的图像进行了平移。因此,我们用这种最简单粗暴的方式来得到我们想要的效果。
问题:为什么呢?
答:请允许我使用下图中的回答。
- 放大招:整体代码如下:
// csdn_code.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <opencv2/opencv.hpp>using namespace cv;using namespace std;//#define IMG_PATH "..//figures//12.jpg"#define IMG_PATH "..//figures//lotus.jpg"int main(){ Mat img = imread(IMG_PATH); if (img.empty()) cerr<<"can not load image"<<endl; // 定义仿射变换的,中心,角度,尺度 Point2f center; center = Point2f(0,0); double degree = 45; double scale = 1; // 旋转 45 度的例子 Mat rot = getRotationMatrix2D(center,degree,scale); Mat rimg; warpAffine(img,rimg,rot,img.size()); imshow("45",rimg); // 定义仿射变换的,中心,角度,尺度 // !!! 注意,这里变换之前的中心必须为 原图的中心 !!! center = Point2f(img.cols/2.0, img.rows/2.0); degree = 60; scale = 1; // 获取变换矩阵 rot = getRotationMatrix2D(center,degree,scale); rimg; warpAffine(img,rimg,rot,img.size()); imshow("img",img); imshow("rimg",rimg); // 获取变换之后的 区域,这个很重要,不然的话,变换之后的图像显示不全 Rect bbox; bbox = RotatedRect(center,Size(scale*img.cols,scale*img.rows),degree).boundingRect(); // 对变换矩阵的最后一列做修改,重新定义变换的 中心 rot.at<double>(0,2) += bbox.width/2 - center.x; rot.at<double>(1,2) += bbox.height/2 - center.y; Mat dst; warpAffine(img,dst,rot, bbox.size()); imshow("dst",dst); waitKey(); system("pause"); return 0;}
- OpenCV2.4.13中warpAffine函数理解,旋转,仿射变换,缩放,保持完整图片
- 仿射变换函数warpAffine、旋转
- OpenCV—仿射变换warpAffine--旋转和缩放
- 【学习OpenCV】仿射变换函数warpAffine、旋转
- 【学习OpenCV】仿射变换函数warpAffine、旋转
- 用OpenCV的仿射变换函数warpAffine实现图像的任意角度旋转!
- opencv 3.0 仿射变换 图形旋转 getRotationMatrix2D warpAffine
- 仿射变换详解 warpAffine
- 仿射变换详解 warpAffine
- 用opencv中的warpAffine获取仿射变换图片保存
- view仿射变换 缩放 旋转 平移
- 仿射变换---位移+缩放比例+旋转
- opencv学习-imgprocess-仿射变换warpAffine
- opencv3计算变换矩阵getAffineTransform函数和进行仿射变换warpAffine函数
- opencv3计算变换矩阵getAffineTransform函数和进行仿射变换warpAffine函数-滚动条
- Opencv3图片旋转(仿射变换)
- 【OpenCV】仿射变换:坐标计算 旋转 缩放
- transform的仿射变换,旋转、缩放、位移
- 新增
- 编程素养018
- kill -3dumpStackTraces
- 506. Relative Ranks
- 中兴程序员跳楼事件始末解读
- OpenCV2.4.13中warpAffine函数理解,旋转,仿射变换,缩放,保持完整图片
- VMware 新建Ubuntu 环境后的基础参数设置(主机名、ip地址、域名映射、防火墙等)
- 6卡驱动win10,矿机专业驱动
- 7.6、数据缓存
- 173. Spring Boot WebSocket:群聊
- 数据库死锁及解决死锁问题
- [POJ1664] 放苹果
- 购物车
- 兄弟连学python-关于lambda表达式