7.3 重映射

7.3.1 概念

1.重映射是把图像中某位置的像素放置到另一图片指定位置的过程,通过重映射表达像素位置:
                   g(x,y)=f(h(x,y))
          g()是目标图像,f()是原图像,h(x,y)是作用于(x,y)的映射方法函数
2.函数:remap()函数,根据指定的映射形式,将源图像进行重映射几何变换,基于以下公式:
                
3.函数原型:

void remap(InputArray src, OuptutArray dst, InputArray map1, InputArray map2, int interpolation, intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())

4.参数说明:
(1)输入图像,单通道8位或浮点型图像
(2)输出图像,与原图像有一样尺寸和类型
(3)两种可能表示:1)表示点(x,y)的第一个映射 2)表示CV_16SC2、CV_32FC1或CV_32FC2类型的x值
(4)两种可能表示:1)map1表示点(x,y)时,参数不代表任何值 2)表示CV_16UC1、CV_32FC1类型的y值
(5)插值方式,可选插值方式:
   1)INTER_NEAREST–最近邻插值
   2)INTER_LINEAR–双线性插值(默认值)
   3)INTER_CUBIC–双三次样条插值(超过44像素邻域内的双三次插值)
   4)INTER_LANCZOS4–Lanczos插值(超过8
8像素领域的Lanczos插值)
(6)边界模式,默认值BORDER_CONSTANT,表示目标图像中“离群点”像素值不会被此函数修改
(7)当有常数边界时使用的值,默认Scalar()
5.调用示例:

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{//变量定义Mat srcImage, dstImage;Mat map_x, map_y;//载入原图srcImage = imread("love.jpg");if (!srcImage.data){printf("载入原图失败~!\n");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 i = 0; i < srcImage.rows; i++){for (int j = 0; j < srcImage.cols; j++){map_x.at<float>(i, j) = static_cast<float>(j);map_y.at<float>(i, j) = static_cast<float>(srcImage.rows - i);}}//重映射操作remap(srcImage, dstImage, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));//显示效果图imshow("【效果图】", dstImage);waitKey(0);return 0;
}

运行效果:

7.3.2 综合示例

/*
效果:
按键控制实现4种不同重映射模式
*/
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
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);
static void ShowHelpText();int main()
{//改变console字体颜色system("color 2F");//显示帮助文字ShowHelpText();//【1】载入原图g_srcImage = imread("3.jpg");if (!g_srcImage.data){ printf("载入原图失败~!\n");return false; }//【2】创建和原图一样的效果图,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);//【3】创建窗口并显示namedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE);imshow(WINDOW_NAME, g_srcImage);//【4】轮询按键,更新map_x和map_y的值,进行重映射操作并显示效果图while (1){//获取键盘按键  int key = waitKey(0);//判断ESC是否按下,若按下便退出  if ((key & 255) == 27){cout << "程序退出...........\n";break;}//根据按下的键盘按键来更新 map_x & map_y的值. 然后调用remap( )进行重映射update_map(key);remap(g_srcImage, g_dstImage, g_map_x, g_map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));//显示效果图imshow(WINDOW_NAME, g_dstImage);}return 0;
}//update_map( )函数:根据按键来更新map_x与map_x的值
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){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) = 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': // 键盘【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': // 键盘【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': // 键盘【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 0;
}static void ShowHelpText()
{printf("\n\n\n\t欢迎来到重映射示例程序~\n\n");printf("\n\n\t按键操作说明: \n\n");printf("\t\t键盘按键【ESC】- 退出程序\n");printf("\t\t键盘按键【1】-  第一种映射方式\n");printf("\t\t键盘按键【2】- 第二种映射方式\n");printf("\t\t键盘按键【3】- 第三种映射方式\n");printf("\t\t键盘按键【4】- 第四种映射方式\n");
}

运行效果:


         映射模式1                映射模式2

        映射模式3                 映射模式4

《OpenCV3编程入门》学习笔记7 图像变换(三 )重映射相关推荐

  1. 原创 OpenCV3编程入门 学习笔记(总)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_36163358/article/ ...

  2. OpenCV3编程入门 学习笔记(总)

    OpenCV3编程入门 学习笔记 2018.12.12-2018.12.29 此博客为在看过毛星云版<OpenCV3编程入门>后所总结的一本笔记,可供复习使用. 文章目录 OpenCV3编 ...

  3. Opencv3编程入门学习笔记(五)之通道分离(split)与合并(merge)

    若要对Opencv中(BGR)颜色通道进行单一处理,那必然会涉及到通道分离(split)与合并(merge).那么本篇博客笔者记录了两个方法的使用方法和案例.案例来源于<Opencv3编程入门学 ...

  4. Opencv3编程入门学习笔记(三)之访问图像像素的三种方法

    访问图像像素的三种方法:指针访问,迭代器访问,动态地址访问.访问最快的为指针访问,以下算法在几毫秒,但指针访问容易造成内存泄漏:其次为迭代器访问:最后为动态地址访问. 以下程序是根据<OpenC ...

  5. 【OpenCV3编程入门学习笔记】——第1章 邂逅OpenCV

    邂逅OpenCV 文章目录 邂逅OpenCV 前言 1.1 OpenCV周边概念认知 1.1.1 图像处理.计算机视觉与OpenCV 1.1.2 OpenCV概述 1.1.3 起源及发展 1.1.4 ...

  6. Opencv3编程入门学习笔记(四)之split通道分离Debug过程中0xC0000005内存访问冲突问题

    这是笔者学习<Opencv3编程入门>的第四篇博客,这篇博客主要是解决在Windows系统下VS 2013中Debug含有split分离通道色彩函数时报出的0xC0000005内存访问冲突 ...

  7. 【OpenCV3编程入门学习笔记】——第3章 HighGUI图形用户界面初步

    文章目录 前言 3.1 图形的载入.显示和输出到文件 3.1.1 OpenCV的命名空间 3.1.2 Mat类简析 3.1.3 图像的载入与显示概述 3.1.4 图像的载入:imread()函数 3. ...

  8. Opencv3编程入门学习笔记(二)之显式创建Mat对象

    以下总结是基于<Opencv3编程入门>一书4.1节总结的内容进行验证与总结,验证环境均为Windows10 ---VS2013 C++环境,验证Opencv3.0提供的开发包. 1. 方 ...

  9. 01.Java 编程入门学习笔记20210307

    Java 编程入门学习笔记-day01 第0章:编程入门 1.计算机的概述 计算机 = 硬件 + 软件 1.1硬件:冯诺依曼体系 CPU: CPU的衡量标准:速度的计量单位是赫兹(Hz),1Hz相当于 ...

  10. Python快速编程入门#学习笔记01# |第一章 :Python基础知识 (Python发展历程、常见的开发工具、import模块导入)

    全文目录 ==先导知识== 1 认识Python 1.1.1 Python的发展历程 1.1.2 Python语言的特点 2. Python解释器的安装与Python程序运行 1.2.1 安装Pyth ...

最新文章

  1. 无线路由器打印机服务器设置密码,路由器怎么设置打印机服务器设置
  2. 千兆网卡为什么慢_千兆宽带普及率不到1% 消费者为何不愿意用千兆宽带?
  3. ceph monitor----paxos算法1
  4. 微服务架构下的安全认证与鉴权
  5. mysql 数据库事务处理_Mysql事务处理问题 - mysql数据库栏目 - 自学php
  6. 我们分析了全美Top Business Analyst 和 Data Science专业,最后给你总结了这几点
  7. Alibaba Sentinel 限流与熔断初探
  8. 思科命令 service password-encryption
  9. IDEA下maven工程找不到@Test
  10. MySQL学习-MySQL数据库事务
  11. pytorch学习笔记(二十六):NIN
  12. windows phone7 学习笔记06——数据绑定
  13. python精彩编程200例-python趣味编程100例(99个)
  14. vmware windows linux udp通信,windows 下 udp socket
  15. php 密码加密方法
  16. 数字天堂陷入困境_我如何从陷入困境和绝望变成实现我的技术职业梦想
  17. openCV 出现 0x770413C5 (ntdll.dll) 第一机会异常: 0xC0000005: 读取位置 0x00000008 时发生访问冲突 解决办法
  18. windows 10下 opessl 64位编译
  19. iphone7plus启动时icon被拉伸放大的原因
  20. 最新vx红包封面小程序源码 附教程

热门文章

  1. 2022-2028年中国露天采矿行业调查与投资前景评估报告
  2. 2022-2028年中国非溶聚丁苯橡胶行业市场竞争态势及发展前景分析报告
  3. Go 学习笔记(74)— Go 标准库之 unsafe
  4. OpenCV 笔记(09)— 常用的数据结构和函数(Vec、Point、Scalar、Size、Rect、cvtColor)
  5. Pandas_transform的用法
  6. 各种优化算法公式快速回忆优化器-深度学习
  7. 万事开头难!最新MyBatis程序配置教程(IDEA版)
  8. 个性化排序的神经协同过滤
  9. NVIDIA GPUs上深度学习推荐模型的优化
  10. Java List 更换指定位置的元素