今天学习了一个比较简单的内容,叫图像的重映射。思想很简单,就和中学学的函数映射差不多,定义x和y方向的映射表就能实现。所谓的映射表就是指用来确定生成图像的每个像素点对应于原图的位置。涉及的函数如下:
(1)remap(源Mat对象,目标Mat对象,x方向的映射表,y方向的映射表)//注意这里的映射表是Mat类对象(虽然我觉得用一维数组就行了),关于映射表内容的解释看代码注释
代码演示:
#include<opencv2\opencv.hpp>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;
using namespace cv;
Mat src, dst, mat_x, mat_y;
int index = 0;
void updateMap();
int main()
{
src = imread("1.jpg", 1);
if (src.empty())
{
printf("cannot load!!\n");
system("pause");
return -1;
}
namedWindow("原图");
imshow("原图", src);
//生成x,y映射表
mat_x.create(src.size(), CV_32FC1);//映射表只能是32FC1或者32FC2类型
mat_y.create(src.size(), CV_32FC1);
//重映射
while (true)
{
updateMap();
remap(src, dst, mat_x, mat_y, INTER_LINEAR);
namedWindow("效果");
imshow("效果",dst);
if (waitKey(1000) != 0xff)
break;
index = (index + 1) % 4;
}
waitKey(0);
return 0;
}
void updateMap()//更新映射表
{
int height = src.rows, width = src.cols;
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
switch (index)
{
case 0://缩小一半
if (col > width*0.25&&col<width*0.75&&row>height*0.25&&row < height*0.75)
{
mat_x.at<float>(row, col) = 2 * col - width*0.5;//mat_x每个点存的值代表生成图像的(row,col)位置对应于原图的哪一列
mat_y.at<float>(row, col) = 2 * row - height*0.5;//mat_y每个点存的值代表生成图像的(row,col)位置对应于原图的哪一列
}
else
{
mat_x.at<float>(row, col) = 0;
mat_y.at<float>(row, col) = 0;
}
break;
case 1://左右互换
mat_x.at<float>(row, col) = width - col;
mat_y.at<float>(row, col) = row;
break;
case 2://上下互换
mat_x.at<float>(row, col) = col;
mat_y.at<float>(row, col) = height - row;
break;
case 3://对角线互换
mat_x.at<float>(row, col) = width - col;
mat_y.at<float>(row, col) = height - row;
break;
}
}
}
}
演示效果: