重映射是什么意思?

  • 把一个图像中一个位置的像素放置到另一个图片指定位置的过程.

  • 为了完成映射过程, 有必要获得一些插值为非整数像素坐标,因为源图像与目标图像的像素坐标不是一一对应的.

  • 我们通过重映射来表达每个像素的位置  :

    这里  是目标图像,  是源图像,  是作用于  的映射方法函数.

让我们来思考一个快速的例子. 想象一下我们有一个图像  , 我们想满足下面的条件作重映射:

会发生什么? 图像会按照  轴方向发生翻转.

映射函数 remap. 参数说明:

代码如下:

  1. #include "opencv2/highgui/highgui.hpp"
  2. #include "opencv2/imgproc/imgproc.hpp"
  3. #include <iostream>
  4. #include <stdio.h>
  5.  
  6. using namespace cv;
  7.  
  8. /// Global variables
  9. Mat src, dst;
  10. Mat map_x, map_y;
  11. char* remap_window = "Remap demo";
  12. int ind = ;
  13.  
  14. /// Function Headers
  15. void update_map(void);
  16.  
  17. /**
  18. * @function main
  19. */
  20. int main(int argc, char** argv)
  21. {
  22. /// Load the image
  23. src = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\06.jpg", );
  24.  
  25. /// Create dst, map_x and map_y with the same size as src:
  26. dst.create(src.size(), src.type());
  27. map_x.create(src.size(), CV_32FC1);
  28. map_y.create(src.size(), CV_32FC1);
  29.  
  30. /// Create window
  31. namedWindow(remap_window, CV_WINDOW_AUTOSIZE);
  32.  
  33. /// Loop
  34. while (true)
  35. {
  36. /// Each 1 sec. Press ESC to exit the program
  37. int c = waitKey();
  38.  
  39. if ((char)c == )
  40. {
  41. break;
  42. }
  43.  
  44. /// Update map_x & map_y. Then apply remap
  45. update_map();
  46. remap(src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(, , ));
  47.  
  48. /// Display results
  49. imshow(remap_window, dst);
  50. }
  51. return ;
  52. }
  53.  
  54. void update_map(void)
  55. {
  56. ind = ind % ;
  57.  
  58. for (int j = ; j < src.rows; j++)
  59. {
  60. for (int i = ; i < src.cols; i++)
  61. {
  62. switch (ind)
  63. {
  64. case :
  65. if (i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75)
  66. {
  67. map_x.at<float>(j, i) = * (i - src.cols*0.25) + 0.5;
  68. map_y.at<float>(j, i) = * (j - src.rows*0.25) + 0.5;
  69. }
  70. else
  71. {
  72. map_x.at<float>(j, i) = ;
  73. map_y.at<float>(j, i) = ;
  74. }
  75. break;
  76. case :
  77. map_x.at<float>(j, i) = i;
  78. map_y.at<float>(j, i) = src.rows - j;
  79. break;
  80. case :
  81. map_x.at<float>(j, i) = src.cols - i;
  82. map_y.at<float>(j, i) = j;
  83. break;
  84. case :
  85. map_x.at<float>(j, i) = src.cols - i;
  86. map_y.at<float>(j, i) = src.rows - j;
  87. break;
  88. } // end of switch
  89. }
  90. }
  91. ind++;
  92. }

主要代码说明:

建立一个间隔1000毫秒的循环,每次循环执行更新映射矩阵参数并对源图像进行重映射处理(使用 mat_x 和 mat_y),然后把更新后的目标图像显示出来:

重映射函数 remap. 参数说明:

  • src: 源图像
  • dst: 目标图像,与 src 相同大小
  • map_x: x方向的映射参数. 它相当于方法  的第一个参数
  • map_y: y方向的映射参数. 注意 map_y 和 map_x 与 src 的大小一致。
  • CV_INTER_LINEAR: 非整数像素坐标插值标志. 这里给出的是默认值(双线性插值).
  • BORDER_CONSTANT: 默认
  1. while (true)
  2. {
  3. /// Each 1 sec. Press ESC to exit the program
  4. int c = waitKey(1000);
  5.  
  6. if ((char)c == 27)
  7. {
  8. break;
  9. }
  10.  
  11. /// Update map_x & map_y. Then apply remap
  12. update_map();
  13. remap(src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
  14.  
  15. /// Display results
  16. imshow(remap_window, dst);
  17. }
  18. return 0;
  19. }

  我们做了什么哪些映射过程?(在这里 map_x 代表第一个坐标 h(i,j) , map_y 是第二个坐标,映射后的坐标)

  1. void update_map(void)
  2. {
  3. ind = ind % ;
  4.  
  5. for (int j = ; j < src.rows; j++)
  6. {
  7. for (int i = ; i < src.cols; i++)
  8. {
  9. switch (ind)
  10. {
  11. case :
  12. if (i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75)
  13. {
  14. map_x.at<float>(j, i) = * (i - src.cols*0.25) + 0.5;
  15. map_y.at<float>(j, i) = * (j - src.rows*0.25) + 0.5;
  16. }
  17. else
  18. {
  19. map_x.at<float>(j, i) = ;
  20. map_y.at<float>(j, i) = ;
  21. }
  22. break;
  23. case :
  24. map_x.at<float>(j, i) = i;
  25. map_y.at<float>(j, i) = src.rows - j;
  26. break;
  27. case :
  28. map_x.at<float>(j, i) = src.cols - i;
  29. map_y.at<float>(j, i) = j;
  30. break;
  31. case :
  32. map_x.at<float>(j, i) = src.cols - i;
  33. map_y.at<float>(j, i) = src.rows - j;
  34. break;
  35. } // end of switch
  36. }
  37. }
  38. ind++;

结果如下:

图像宽高缩小一半,并显示在中间:

图像上下颠倒:

图像左右颠倒:

两个方向同时颠倒:

OpenCV函数 重映射的更多相关文章

  1. opencv —— remap 重映射

    重映射的概念 重映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程. 实现重映射:remap 函数 将图像进行重映射几何变换,基于的公式为:dst (x, y) = src ( mapx ...

  2. opencv之重映射

    好久没写呆码了 今天发个重映射 #include "opencv2/video/tracking.hpp" #include "opencv2/imgproc/imgpr ...

  3. opencv::像素重映射

    像素重映射(cv::remap) 简单点说就是把输入图像中各个像素按照一定的规则映射到另外一张图像的对应位置上去,形成一张新的图像. Remap( InputArray src, // 输入图像 Ou ...

  4. 【OpenCV新手教程之十七】OpenCV重映射 &amp; SURF特征点检測合辑

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

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

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

  6. OpenCV学习笔记(九) 重映射、仿射变换

    重映射 通过重映射来表达每个像素的位置  : 这里  是目标图像,  是源图像,  是作用于  的映射方法函数.想象一下我们有一个图像  , 我们想满足下面的条件作重映射:,图像会按照  轴方向发生翻 ...

  7. opencv 5 图像转换(3 重映射 仿射变换 直方图均衡化)

    重映射 实现重映射(remap函数) 基础示例程序:基本重映射 //---------------------------------[头文件.命名空间包含部分]------------------- ...

  8. 单片机中printf函数的重映射

    单片机中printf函数的重映射 一.源自于:大侠有话说 1.如果你在学习单片机之前学过C语言,那么一定知道printf这个函数.它最最好用的功能 除了打印你想要的字符到屏幕上外,还能把数字进行格式化 ...

  9. OpenCV——重映射、仿射变换

    #include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespac ...

随机推荐

  1. 剑指offer-面试题15-二进制中1的个数-位运算

    /* 题目: 二进制中1的个数,例如9为1001,有2位1. */ /* 思路: 算法2: 左移unsigned类型flag=1,和n做&运算,当flag移动中1的位置与n对应位置也为1时,则 ...

  2. 学习django3过程中的坑

    最近跟着Django by Example 2015学习,可老想用最新版的Django3.在学的过程中可踩了不少坑. 今天就又碰到一个: 在这本书中96页有这样的代码: url(r'^login/$' ...

  3. install multiple versions of CUDA

    https://www.pugetsystems.com/labs/hpc/How-To-Install-CUDA-10-together-with-9-2-on-Ubuntu-18-04-with- ...

  4. Selenium3+python自动化016-Selenium Grid

    一.Selenium Grid介绍 1.概念 Selenium Grid组件专门用于远程分布式测试或并发测试,通过并发执行测试用例的方式可以提高测试用例的执行速度和效率,解决界面自动化测试执行速度过慢 ...

  5. [Err] 1248 - Every derived table must have its own alias

    问题描述 [Err] 1248 - Every derived table must have its own alias 问题原因 这句话的意思是说每个派生出来的表都必须有一个自己的别名 我的Mys ...

  6. C语言实现顺序栈

    C语言实现顺序栈,顺便加深刻++i,++i的区别 #include <stdio.h>#include <stdlib.h>#define maxsize 100/*写在前面的 ...

  7. koa文档笔记

    请求 get ctx.request.query // 查询对象 ctx.request.querystring // 查询字符串 ctx.query // 查询对象 ctx.querystring ...

  8. java学习笔记之IO编程—对象序列化

    对象序列化就是将内存中保存的对象以二进制数据流的形式进行处理,可以实现对象的保存或网络传输. 并不是所有的对象都可以被序列化,如果要序列化的对象,那么对象所在的类一定要实现java.io.Serial ...

  9. GD库的基本信息,图像的旋转、水印、缩略图、验证码,以及图像类的封装

    GD库检测 <?php phpinfo(); ?> GD库安装• Windows 使用phpstudy • Linux 编译安装 –with-gd• Linux 编译安装扩展 GD库支持的 ...

  10. Mysql中FIND_IN_SET()和IN区别简析

    来源:http://www.jb51.net/article/125744.htm 测试SQL: CREATE TABLE `test` ( `id` int(8) NOT NULL auto_inc ...