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

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

猜你喜欢

转载自blog.csdn.net/ccchenxi/article/details/85109477
今日推荐