Opencv3笔记18——重映射

2019-04-15 16:01发布

class="markdown_views prism-atelier-sulphurpool-light">

1 重映射的概念

重映射就是把一副图像中某位置的像素放置到另一个图片指定位置的过程,为了完成映射过程,需要获得一些插值为非整数像素的坐标。
g(x,y)=f(h(x,y))" role="presentation">g(x,y)=f(h(x,y))
* g()" role="presentation">g()是目标图像
* f()" role="presentation">f()是源图像
* h(x,y)" role="presentation">h(x,y)是作用于(x,y)" role="presentation">(x,y)的映射方法函数

2 实现重映射:remap()函数

公式为:
dst(x,y)=src(mapx(x,y),mapy(x,y))" role="presentation">dst(x,y)=src(mapx(x,y),mapy(x,y))
函数原型:不支持就地(in-place)操作 void remap(InputArray src,OutputArray dst, InputArray map1,InputArray map2,int interpolation,intborderMode = BORDER_CONSRANT, const Scalar & borderValue = Scalar() ) 这里写图片描述

3 基本重映射

#include #include #include using namespace cv; //main()函数 int main() { //变量定义 Mat srcImage, dstImage; Mat map_x, map_y; //载入原图 srcImage = imread("1.jpg"); if (!srcImage.data) { printf("读取文件错误,请确定目录下是否有imread函数~! "); 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.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, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0)); //显示效果图 imshow("【程序窗口】", dstImage); waitKey(); return 0; } 这里写图片描述

4 综合示例

#include #include #include using namespace cv; using namespace std; //定义宏部分 #define WINDOW_NAME "【程序窗口】" //全局变量 //原图和目标图 Mat g_srcImage, g_dstImage; Mat g_map_x, g_map_y; //全局函数的声明 int update_map(int key); //main()函数 int main() { //改变console字体颜 {MOD} system("color 2F"); //载入原图 g_srcImage = imread("1.jpg"); if (!g_srcImage.data) { printf("读取文件错误~! "); return false; } //创建与原始图一样的效果图,x重映射图,y重映射图 g_dstImage.create(g_srcImage.size(), g_srcImage.type()); g_map_x.create(g_srcImage.size(), CV_32FC1); g_map_y.create(g_srcImage.size(), CV_32FC1); //创建窗口并显示 namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE); imshow(WINDOW_NAME, g_srcImage); //轮询按键 while (1) { //获取键盘按键 int key = waitKey(0); //判断ESC是否被按下 if ((key & 255) == 27) { cout << "程序退出。。。。。。。。。 "; break; } //根据按下的键盘按键更行map_x,map_y的值,然后调用remap()进行重映射 update_map(key); remap(g_srcImage, g_dstImage, g_map_x, g_map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0)); imshow(WINDOW_NAME, g_dstImage); } return 0; } // update_map()函数 int update_map(int key) { for (int j = 0; j < g_srcImage.rows; j++) { for (int i = 0; i < g_srcImage.cols; i++) { switch (key) { //键盘1被按下,进行第一种重映射变换 case '1': if (i > g_srcImage.cols*0.25 && i0.75 && j>g_srcImage.rows*0.25 && j < g_srcImage.rows*0.75) { g_map_x.at<float>(j, i) = static_cast<float>(2 * (i - g_srcImage.cols*0.25) + 0.5); g_map_y.at<float>(j, i) = static_cast<float>(2 * (j - g_srcImage.rows*0.25) + 0.5); } else { g_map_x.at<float>(j, i) = 0; g_map_y.at<float>(j, i) = 0; } break; case '2': g_map_x.at<float>(j, i) = static_cast<float>(i); g_map_y.at<float>(j, i) = static_cast<float>(g_srcImage.rows - j); break; case '3': g_map_x.at<float>(j, i) = static_cast<float>(g_srcImage.cols - i); g_map_y.at<float>(j, i) = static_cast<float>(j); break; case '4': g_map_x.at<float>(j, i) = static_cast<float>(g_srcImage.cols - i); g_map_y.at<float>(j, i) = static_cast<float>(g_srcImage.rows - j); break; default: break; } } } return 1; } 这里写图片描述 这里写图片描述
这里写图片描述 这里写图片描述 这里写图片描述