我是靠谱客的博主 要减肥花瓣,这篇文章主要介绍图像重映射与仿射映射,现在分享给大家,希望可以做个参考。

一、重映射

1.1 重映射的思想

    重映射就是图像像素位置转移的过程。由于原图和目标图的像素坐标并不是一一对应的,所以要进行非整数像素插值。主要思路是将映射方法函数作用于原图,输出目标图。
在这里插入图片描述
1.2 重映射的实现

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> using namespace cv; int main( ) { //变量定义 Mat srcImage, dstImage; Mat map_x, map_y; //载入原始图 srcImage = imread( "腾云.jpg", 1 ); if(!srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! n"); return false; } imshow("原始图",srcImage); //创建和原始图一样的效果图,x重映射图,y重映射图 dstImage.create( srcImage.size(), srcImage.type() ); map_x.create( srcImage.size(), CV_32FC1 ); map_y.create( srcImage.size(), CV_32FC1 ); //双层循环,遍历每一个像素点,改变map_x & map_y的值 for( int j = 0; j < srcImage.rows;j++) { for( int i = 0; i < srcImage.cols;i++) { //改变map_x & map_y的值. map_x.at<float>(j,i) = static_cast<float>(i); map_y.at<float>(j,i) = static_cast<float>(srcImage.rows - j); } } //进行重映射操作 remap( srcImage, dstImage, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) ); //显示效果图 imshow( "效果图", dstImage ); waitKey(); return 0; }

    说明:1、static_cast是命名的强制转换,任何具有明确定义的类型转换,只要不包含底层const,都可以使用它。这里是把已经定义的整型i强制转换成浮点型。一般形式为:cast-name<type>(expression)
其中,type是要转换的目标类型,expression是要转换的值。cast-name可以是static_castdynamic_castconst_castreinterpret_cast中的一种,它指定了那种类型的转换。
2、remap()函数的七个参数分别代表输入图像、输出图像、CV_32FC1类型的X值、CV_32FC1类型的Y值、双线性插值方式、边界模式和borderValue。

1.3 运行结果

图1.1 原始图

在这里插入图片描述
图1.2 重映射效果图

二、仿射映射

2.1 仿射映射的概念

    一个向量空间进行一次线性变换和平移,变换到另一个向量空间的过程。遵循“平直性”和“平行性”,即直线变换之后依然是直线,平行线变换之后依然是平行线。基于公式:
在这里插入图片描述
2.2 仿射映射变换的实现

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> using namespace cv; using namespace std; //宏定义 #define WINDOW_NAME1 "【原始图窗口】" //为窗口标题定义的宏 #define WINDOW_NAME2 "【经过Warp后的图像】" //为窗口标题定义的宏 #define WINDOW_NAME3 "【经过Warp和Rotate后的图像】" //为窗口标题定义的宏 int main( ) { //参数准备 //定义两组点,代表两个三角形 Point2f srcTriangle[3]; Point2f dstTriangle[3]; //定义一些Mat变量 Mat rotMat( 2, 3, CV_32FC1 ); Mat warpMat( 2, 3, CV_32FC1 ); Mat srcImage, dstImage_warp, dstImage_warp_rotate; //加载源图像并作一些初始化 srcImage = imread( "腾云.jpg", 1 ); if(!srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! n"); return false; } // 设置目标图像的大小和类型与源图像一致 dstImage_warp = Mat::zeros( srcImage.rows, srcImage.cols, srcImage.type() ); //设置源图像和目标图像上的三组点以计算仿射变换 srcTriangle[0] = Point2f( 0,0 ); srcTriangle[1] = Point2f( static_cast<float>(srcImage.cols - 1), 0 ); srcTriangle[2] = Point2f( 0, static_cast<float>(srcImage.rows - 1 )); dstTriangle[0] = Point2f( static_cast<float>(srcImage.cols*0.0), static_cast<float>(srcImage.rows*0.33)); dstTriangle[1] = Point2f( static_cast<float>(srcImage.cols*0.65), static_cast<float>(srcImage.rows*0.35)); dstTriangle[2] = Point2f( static_cast<float>(srcImage.cols*0.15), static_cast<float>(srcImage.rows*0.6)); //求得仿射变换 warpMat = getAffineTransform( srcTriangle, dstTriangle ); //对源图像应用刚刚求得的仿射变换 warpAffine( srcImage, dstImage_warp, warpMat, dstImage_warp.size() ); //对图像进行缩放后再旋转 // 计算绕图像中点顺时针旋转50度缩放因子为0.6的旋转矩阵 Point center = Point( dstImage_warp.cols/2, dstImage_warp.rows/2 ); double angle = -50.0; double scale = 0.6; // 通过上面的旋转细节信息求得旋转矩阵 rotMat = getRotationMatrix2D( center, angle, scale ); // 旋转已缩放后的图像 warpAffine( dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.size() ); //显示结果 imshow( WINDOW_NAME1, srcImage ); imshow( WINDOW_NAME2, dstImage_warp ); imshow( WINDOW_NAME3, dstImage_warp_rotate ); // 等待用户按任意按键退出程序 waitKey(0); return 0; }

    说明:warpAffine()函数中的参数分别表示输入图像、输出图像、2*3的变换矩阵和输出图像的尺寸。

2.3 变换结果

在这里插入图片描述

图2.1 原始图

在这里插入图片描述
图2.2 Warp后的图像

在这里插入图片描述
图2.3 Warp和Rotate后的图像

最后

以上就是要减肥花瓣最近收集整理的关于图像重映射与仿射映射的全部内容,更多相关图像重映射与仿射映射内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(64)

评论列表共有 0 条评论

立即
投稿
返回
顶部