重映射:就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。
一般情况下,我们通过重映射来表达每个像素的位置 (x,y),
像这样 : g(x,y) = f ( h(x,y) )
在这里, g( ) 是目标图像, f() 是源图像, 而h(x,y) 是作用于 (x,y) 的映射方法函数。
void remap(
InputArray src, //输入图像
OutputArray dst, //输出图像
InputArray map1, //x轴映射函数map1=f(x),可以将map理解为一个和src同样大小的图像,分成像素块小格,
//每个小格内填入的是src的像素块列号,按照这个规则将src像素块填入输出图像
InputArray map2,//y轴的映射函数map2=f(y)
int interpolation, //插值
intborderMode = BORDER_CONSTANT,//边界模式
const Scalar& borderValue = Scalar()//边界颜色
)
第一个参数:输入图像,即原图像,需要单通道8位或者浮点类型的图像
第二个参数:输出图像,即目标图像,需和原图形一样的尺寸和类型
第三个参数:它有两种可能表示的对象:
(1)表示点(x,y)的第一个映射;
(2)表示CV_16SC2,CV_32FC1等
第四个参数:它有两种可能表示的对象:
(1)若map1表示点(x,y)时,这个参数不代表任何值;
(2)表示 CV_16UC1,CV_32FC1类型的Y值
第五个参数:插值方式,有四中插值方式:
(1)INTER_NEAREST——最近邻插值
(2)INTER_LINEAR——双线性插值(默认)
(3)INTER_CUBIC——双三样条插值(默认)
(4)INTER_LANCZOS4——lanczos插值(默认)
第六个参数:边界模式,默认BORDER_CONSTANT。
第七个参数:边界颜色,默认Scalar()黑色。
以下为函数应用及效果展示:
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat srcImage = imread("D:\\visual studio 2010\\Projects\\remap\\1.jpg");
Mat dstImage,map_x,map_y;
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++)//rows:行
{
for(int i=0;i<srcImage.cols ;i++)
{
//改变map_x和map_y的值
map_x.at<float>(j,i) = static_cast<float>(srcImage.rows -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(255,0,0));
//显示效果图
imshow("效果图",dstImage);
waitKey(0);
return 0;
}
将第二个for循环修改为
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);
}
运行结果:
将第二个for循环修改为:
for(int i=0;i<srcImage.cols ;i++)
{
//改变map_x和map_y的值
//垂直对称
map_x.at<float>(j,i) = static_cast<float>(srcImage.rows -i);
map_y.at<float>(j,i) = static_cast<float>(j);
}
运行结果为: