文章目录

  • 1、重映射的概念
  • 2、实现重映射:remap()函数
  • 3、基本重映射
  • 4、实现多重映射

1、重映射的概念

重映射是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。为了完成重映射过程,需要获得一些插值为非整数像素的坐标,因为源图像与目标图像像素坐标不是一一对应的。如下:
g(x,y)=f(h(x,y))g(x,y)=f(h(x,y)) g(x,y)=f(h(x,y))
g()是目标图像,f()是源图像,而h(x,y)是作用于(x,y)的映射方法函数。

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

remap()函数会根据指定的映射形式,将源图像进行重映射几何变换:
dst(x,y)=src(mapx(x,y),mapy(x,y))dst(x,y)=src(mapx(x,y),mapy(x,y)) dst(x,y)=src(mapx(x,y),mapy(x,y))

void remap(InputArray src,OutputArray dst,InputArray map1,InputArray map2,int interpolation,intborderMode=BORDER_CONSTANT,const Scalar& borderValue=Scalar())
  • 第一个参数:输出图像
  • 第二个参数:函数调用后的运算结果存在这里,即这个参数用于存放函数调用后的输出结果,需和源图片有一样的尺寸和类型
  • 第三个参数:InputArray类型的 map1,有两种可能的表示对象
    • 表示点(x,y)的第一映射
    • 表示CV_16SC2,CV_32FC1,CV_32FC2类型的X值
  • 第四个参数:InputArray类型的 map2,有两种可能的表示对象
    • 若map1表示点(x,y)时,这个参数不代表任何值
    • 表示CV_16UC1,CV_32FC1类型的Y值
  • 第五个参数:int 类型的interpolation,插值方式,所选的插值方式如下:
    • INTER_NEAREST——最近邻插值
    • INTER_LINEAR——双线性插值(默认值)
    • INTER_CUBIC——双三次样条插值
    • INTER_LANCZOS4——Lanczos插值
  • 第六个参数:边界模式
  • 第七个参数:const Scalar&类型的borderValue,当有常数边界使用的值,其默认值Scalar(),即默认值为0

3、基本重映射

说明:下面是精简后的以remap函数为核心的示例程序

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{Mat srcImage, dstImage;Mat map_x, map_y;//载入原始图像srcImage = imread("E:\\Pec\\car.jpg", 1);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_yfor (int j = 0; j < srcImage.rows; j++){for (int i = 0; i < srcImage.cols; i++){//通过at获取像素值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(0);
}

4、实现多重映射

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
#define WINDOW_NAME "【程序窗口】"
Mat g_srcImage, g_dstImage;
Mat g_map_x, g_map_y;
int update_map(int key);
static void ShowHelpText();
int main()
{system("color 2F");ShowHelpText();//载入原始图像g_srcImage = imread("E:\\Pec\\car.jpg", 1);imshow("【原始图】", g_srcImage);//创建和原始图一样的效果图,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);if ((key & 255) == 27){cout << "程序退出......" << endl;break;}update_map(key);//根据按下键盘按键来更新map_x & map_y的值,然后调用remap()进行重映射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;
}
int update_map(int key)
{//双层循环,遍历每一个像素点,改变map_x和Map_yfor (int j = 0; j < g_srcImage.rows; j++){for (int i = 0; i < g_srcImage.cols; i++){switch (key){case '1'://按键1按下,进行第一重映射操作if (i > g_srcImage.cols*0.25&&i<g_srcImage.cols*0.75&&j>g_srcImage.rows*0.25&&j < g_srcImage.rows*0.75){g_map_x.at<float>(j, i) = 2 * (i - g_srcImage.cols*0.25) + 0.5;g_map_y.at<float>(j, i) = 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': //按键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;}}}return 1;
}
static void ShowHelpText()
{cout << "\n\n\n\t欢迎来到重映射示例程序\n";cout << "\n\n\n\t按键操作如下:" ;cout << "\n\n\n\t键盘按下【ESC】-退出程序" ;cout << "\n\n\n\t键盘按下【1】-第一种映射方式,缩小2倍" ;cout << "\n\n\n\t键盘按下【2】-第二种映射方式,y方向翻转" ;cout << "\n\n\n\t键盘按下【3】-第三种映射方式,x方向反转" ;cout << "\n\n\n\t键盘按下【4】-第四种映射方式,x,y方向反转" ;
}

第一种映射方式,缩小2倍

第二种映射方式,y方向翻转

第三种映射方式,x方向反转

第四种映射方式,x,y方向反转

【OpenCV】-重映射相关推荐

  1. 【OpenCV入门教程之十七】OpenCV重映射 SURF特征点检测合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/30974513 作者:毛星云(浅墨) ...

  2. opencv 重映射、x轴翻转,y轴翻转,xy轴镜像,图像缩小

    本章内容 重映射.x轴翻转,y轴翻转,xy轴镜像,图像缩小 输出结果: 源码 #include <ostream> #include <opencv.hpp> #include ...

  3. OpenCV:remap()简单重映射

    学习自:[OpenCV入门教程之十七]OpenCV重映射 重映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程. 为了完成映射过程, 我们需要获得一些插值为非整数像素的坐标,因为源图像与 ...

  4. 【OpenCV 】Remapping 重映射¶

    目录 1.1目标 1.2 理论 1.3 代码 1.4 运行结果 1.1目标 展示如何使用OpenCV函数 remap 来实现简单重映射. 1.2 理论 把一个图像中一个位置的像素放置到另一个图片指定位 ...

  5. OpenCV之imgproc 模块. 图像处理(3)霍夫线变换 霍夫圆变换 Remapping 重映射 仿射变换

    霍夫线变换 目标 在这个部分您将学习到: 使用OpenCV的以下函数 HoughLines 和 HoughLinesP 来检测图像中的直线. 原理 Note 以下原理的说明来自书籍 学习OpenCV  ...

  6. OpenCV探索之路(八):重映射与仿射变换

    重映射 重映射就是把一幅图像中某个位置的像素放置到另一个图片中指定位置的过程. 用一个数学公式来表示就是: 其中的 f 就是映射方式,也就说,像素点在另一个图像中的位置是由 f 来计算的. 在Open ...

  7. OpenCV学习笔记(十四):重映射:remap( )

    OpenCV学习笔记(十四):重映射:remap( ) 图像的坐标映射是通过原图像与目标图像之间建立一种映射关系,这种映射关系有两种,一种是计算原图像任意像素在映射后图像的坐标位置,另一种是计算变换后 ...

  8. OpenCV中重映射

    OpenCV中图像重映射 重映射的意思是:把一个图像中一个位置的像素放置到另一个图片指定位置的过程.新图像g(x,y)g(x,y)g(x,y)与原图像f(x,y)f(x,y)f(x,y)存在一个映射的 ...

  9. opencv mat赋值_【3】OpenCV图像处理模块(18)重映射

    本例中使用OpenCV的remap()函数实现简单的图像重映射(remapping). 什么是重映射? 将一幅图像中的像素,改变位置得到一副新的图像,如图像缩放.翻转等. 因为源图像和新图像之间不一定 ...

  10. OpenCV精进之路(七):图像变换——重映射与仿射变换

    重映射 重映射就是把一幅图像中某个位置的像素放置到另一个图片中指定位置的过程. 用一个数学公式来表示就是: 其中的 f 就是映射方式,也就说,像素点在另一个图像中的位置是由 f 来计算的. 在Open ...

最新文章

  1. Android 换肤
  2. 文本挖掘(part7)--Word2vec
  3. ABP文档 - Mvc 视图
  4. Linux学习笔记13
  5. [Ynoi2012]D1T3
  6. 前端架构之路:使用Vue开始第一个项目
  7. Flutter实战一Flutter聊天应用(九)
  8. 年度盘点 | 2016年中国云计算十大新闻
  9. Java添加过期注解
  10. 纯CSS在线气泡提示生成工具 - CSS ARROW PLEASE!
  11. 不重启刷新win7环境变量(注册表)
  12. (附源码)SSM信用卡增值业务系统JAVA计算机毕业设计项目
  13. 【设计】电压电流偏置
  14. 计算机网络说明文,《Wi-Fi》初中说明文阅读题及答案
  15. 三个显示图像的matlab函数图像,如何在matlab中将三个隐函数图像画在同一个图上...
  16. 前端案例——2.仿淘宝关闭二维码案例
  17. mac连接wifi无ip/无法访问网络
  18. speedoffice(Word)怎么修改字体颜色呢
  19. 有一篇文章,共有三行文字,每行有80个字符。要求分别统计出其中英文大写字母,小写字母,数字,空格以及其他字符的个数
  20. yolov5的anchors及bbox的编解码原理

热门文章

  1. win10系统下office2003和office2016兼容
  2. wps2016向程序发送命令_老司机帮您向程序发送命令时出现错误 【操作步骤】 的设置办法...
  3. html网页框架分割三部分,Dreamweaver用框架建立网站把浏览器的显示空间分割为几个部分...
  4. Mathematica公式与Mathtype公式编辑器和MSword互通
  5. [数据采集笔记04]——网页解析——lxml、bs4、正则
  6. bootstrap案例
  7. python安装库之----有些库库真是小妖精
  8. Python语言程序设计课程论文
  9. 20种银河科幻风格ps字体样式
  10. 计算机三维艺术设计基础,计算机艺术设计基础(修订版)