1.目的
(1)如何使用openCV函数remap实现简单的重映射
2.原理
把一个图像中一个位置的像素放置到另一个图片指定位置的过程,为了完成映射过程, 有必要获得一些插值为非整数像素坐标,因为源图像与目标图像的像素坐标不是一一对应的。我们通过重映射来表达每个像素的位置(x,y):
g(x,y)= f(h(x,y))
这里 g 是目标图像, f 是源图像, h(x,y) 是作用于 (x,y) 的映射方法函数。
3.部分代码解释
(1)remap
/*
Remapping参数解释
src:输入图像
dst:输出图像
map_x:表示点(x,y)的x映射,CV_32FC1或者CV_16SC2类型
map_y:表示点(x,y)的y映射,CV_32FC1或者CV_16SC2类型
CV_INTER_LINEAR:非整数插值类型,
包括四个:CV_INTER_LINEAR:双线性插值,
CV_INTER_CUBIC:三样条插值,
CV_INTER_NEAREST:最近临插值,
CV_INTER_LANCZOS4:lanczos插值(默认)
BORDER_CONSTANT:默认边界
Scalar(0,0,0):边界颜色,默认为黑色
*/
remap(src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0,0));
4.完整代码
(1)CommonInclude.h
#ifndef COMMON_INCLUDE
#define COMMON_INCLUDE
#include<iostream>
using namespace std;
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
#endif
(2)Remapping.cpp
#include"CommonInclude.h"
int type = 0;
int max_type = 3;
Mat src, dst;
Mat map_x, map_y;
char windowName[] = "Remapping";
void Mapping(int, void*){
for(int x=0; x<src.rows; x++){
for(int y=0; y<src.cols; y++){
switch(type){
case(0):
if(x>src.rows/4.0 && x < src.rows*3.0/4.0 && y>src.cols/4.0 && y < src.cols*3.0/4.0){
map_x.at<float>(x,y) = 2*(x - src.rows/4.0) + 0.5;
map_y.at<float>(x,y) = 2*(y - src.cols/4.0) + 0.5;
}
//缩放一倍数
break;
case(1):
//左右翻转
map_x.at<float>(x,y) = src.cols - x;
map_y.at<float>(x,y) = y;
break;
case(2):
//上下翻转
map_x.at<float>(x,y) = x;
map_y.at<float>(x,y) = src.rows - y;
break;
case(3):
//中心对称翻转
map_x.at<float>(x,y) = src.cols - x;
map_y.at<float>(x,y) = src.rows - y;
break;
default:
cout << "error type!!!" << endl;
break;
}
}
}
//remapping重新映射
/*
Remapping参数解释
src:输入图像
dst:输出图像
map_x:表示点(x,y)的x映射,CV_32FC1或者CV_16SC2类型
map_y:表示点(x,y)的y映射,CV_32FC1或者CV_16SC2类型
CV_INTER_LINEAR:非整数插值类型,
包括四个:CV_INTER_LINEAR:双线性插值,
CV_INTER_CUBIC:三样条插值,
CV_INTER_NEAREST:最近临插值,
CV_INTER_LANCZOS4:lanczos插值(默认)
BORDER_CONSTANT:默认边界
Scalar(0,0,0):边界颜色,默认为黑色
*/
remap(src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0,0));
imshow(windowName, dst);
}
int main(int argc, char** argv){
if(argc < 2){
cout << "more parameters are required!!!" << endl;
return(-1);
}
src = imread(argv[1]);
if(!src.data){
cout << "error to read image!!!" << endl;
return(-1);
}
//dst.create(src.size(), src.type());
map_x.create(src.size(), CV_32FC1);
map_y.create(src.size(), CV_32FC1);
namedWindow(windowName, CV_WINDOW_AUTOSIZE);
cout << src.size() << endl;
//cvtColor(src, src, CV_BGR2GRAY);
//cout << src.size() << endl;
createTrackbar("Type:\n0:缩放一倍\n1:左右翻转\n2:上下翻转\n3:中心对称翻转", windowName,
&type, max_type,
Mapping);
Mapping(0,0);
waitKey(0);
return(0);
}
参考文献
1.http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/remap/remap.html