OpenCV仿射变换的示例代码
1、认识仿射变换
仿射变换(Affine Map)又称仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间的过程。保持二维图形之间的相对位置保持不变,平行线依然是平行线,且直线上的点的位置顺序不变。
一个任意的仿射变换都可以表示为乘以一个矩阵接着再加上一个向量的形式。三种常见的变换形式:
- 旋转:ratation(线性变换)
- 平移:translation(向量加)
- 缩放:scale(线性变换)
通常使用2 x 3的矩阵来表示仿射变换:
2、仿射变换的求法
说明:仿射变换表示的就是两幅图片之间的一种联系,关于这种联系的信息大致可以分为以下两种场景:
- 已知X和T,而且已知它们是有联系的,接下来的跟着就是求出矩阵M。
- 已知M和X,想要求得T。只要应用算式T=M*X即可。
如上,点1、2、3(在Image 1中形成一个三角形)与Image 2中的三个点是一一映射的关系,且它们仍然形成三角形,但形状已经和之前的不一样的,可以通过这样的两组三点求出仿射变换,然后把这种变换应用到图像中去。
3、进行仿射变换:warpAffine()函数
warpAffine()函数的作用依据下面的公式对图像做仿射变换:
void warpAffine(InputArray class="lazy" data-src,OutputArray dst,InputArray M,Size dsize,int flags=INTER_LINEAR,intborderMOde=BODER_CONSTANT,const Scalar& borderValue=Scalar())
- 第一个参数:输入图像
- 第二个参数:输出图像,函数调用后的运算结果存在这里,需要和源图片有一样的尺寸和类型
- 第三个参数:2 x 3的变换矩阵,求得的仿射变换
- 第四个参数:表示输出图像的尺寸
- 第五个参数:插值方法的标识符。默认值是线性插值法(INTER_LINEAR)
- 第六个参数:边界像素模式
- 第七个参数:在恒定的边界情况下取值,默认值Scalar(),即0
4、计算二维旋转变换矩阵:getRotationMatrix2D()函数
说明:getRotationMatrix2D()函数用于计算二维旋转变换矩阵。变换会将旋转中心映射到它自身
Mat getRotationMatrix2D(Point2f center,double angle,double scale)
- 第一个参数:表示源图像的旋转中心
- 第二个参数:旋转角度。角度为正值表示向逆时针旋转(坐标原点是左上角)
- 第三个参数:缩放系统
5、示例程序:
#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
#define WINDOW_NAME1 "【原始图窗口】"
#define WINDOW_NAME2 "【经过Warp后的窗口】"
#define WINDOW_NAME3 "【经过Warp和Rotate后的窗口】"
int main()
{
system("color 2F");
//参数准备
Point2f class="lazy" data-srcTriangle[3];
Point2f dstTriangle[3];
Mat rotMat(2, 3, CV_32FC1);
Mat warpMat(2, 3, CV_32FC1);
Mat class="lazy" data-srcImage, dstImage_warp, dstImage_warp_rotate;
//加载源图像
class="lazy" data-srcImage = imread("E:\\Pec\\lan.jpg",1);
//设置目标图像的大小和类型与源图像一致
dstImage_warp = Mat::zeros(class="lazy" data-srcImage.rows, class="lazy" data-srcImage.cols, class="lazy" data-srcImage.type());
//设置源图像和目标图像上的三组点以计算仿射变换
//class="lazy" data-srcTriangle[0] = Point2f(0, 0); //Point2f表示Point类的两个数据x,y为float类型;vector 表示存放四维int
//class="lazy" data-srcTriangle[1] = Point2f(static_cast<float>(class="lazy" data-srcImage.cols - 1), 0);
//class="lazy" data-srcTriangle[2] = Point2f(0, static_cast<float>(class="lazy" data-srcImage.rows - 1));
//dstTriangle[0] = Point2f(static_cast<float>(class="lazy" data-srcImage.cols*0.0), static_cast<float>(class="lazy" data-srcImage.rows*0.33));
//dstTriangle[1] = Point2f(static_cast<float>(class="lazy" data-srcImage.cols*0.65), static_cast<float>(class="lazy" data-srcImage.rows*0.35));
//dstTriangle[2] = Point2f(static_cast<float>(class="lazy" data-srcImage.cols*0.15), static_cast<float>(class="lazy" data-srcImage.rows*0.6));
//获取变换矩阵,指定三个点
class="lazy" data-srcTriangle[0] = Point2f(50, 50);
class="lazy" data-srcTriangle[1] = Point2f(200, 50);
class="lazy" data-srcTriangle[2] = Point2f(50, 200);
dstTriangle[0] = Point2f(100, 100);
dstTriangle[1] = Point2f(200, 50);
dstTriangle[2] = Point2f(100, 250);
//求仿射变换,得到一个2x3的矩阵
warpMat = getAffineTransform(class="lazy" data-srcTriangle, dstTriangle);
//对源图像应用刚刚的求得的仿射变换
warpAffine(class="lazy" data-srcImage, dstImage_warp, warpMat, dstImage_warp.size());
//对图像进行缩放后再旋转
//计算图像中点顺时针旋转50°缩放因子为0.6的旋转矩阵
Point center = Point(dstImage_warp.cols / 2, dstImage_warp.rows / 2);
double angle = -30.0;
double scale = 0.8;
//通过上面的旋转细节信息求出旋转矩阵
rotMat = getRotationMatrix2D(center, angle, scale);
//旋转已经缩放后的图像
warpAffine(dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.size());
imshow(WINDOW_NAME1, class="lazy" data-srcImage);
imshow(WINDOW_NAME2, dstImage_warp);
imshow(WINDOW_NAME3, dstImage_warp_rotate);
waitKey(0);
return 0;
}
到此这篇关于OpenCV仿射变换的示例代码的文章就介绍到这了,更多相关OpenCV 仿射变换内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341