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