opencv cv::remap()重映射函数

本文详细介绍了OpenCV库中的remap函数,展示了如何通过修改映射函数实现图像像素的水平或垂直对称重映射,并提供了代码实例。重点在于理解映射规则和插值方法在图像处理中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重映射:就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。
一般情况下,我们通过重映射来表达每个像素的位置 (x,y),
像这样 : g(x,y) = f ( h(x,y) )
在这里, g( ) 是目标图像, f() 是源图像, 而h(x,y) 是作用于 (x,y) 的映射方法函数。

void remap(
InputArray src, //输入图像
OutputArray dst, //输出图像
InputArray map1, //x轴映射函数map1=f(x),可以将map理解为一个和src同样大小的图像,分成像素块小格,
//每个小格内填入的是src的像素块列号,按照这个规则将src像素块填入输出图像
InputArray map2,//y轴的映射函数map2=f(y)
int interpolation, //插值
intborderMode = BORDER_CONSTANT,//边界模式
const Scalar& borderValue = Scalar()//边界颜色
)

第一个参数:输入图像,即原图像,需要单通道8位或者浮点类型的图像
第二个参数:输出图像,即目标图像,需和原图形一样的尺寸和类型
第三个参数:它有两种可能表示的对象:
(1)表示点(x,y)的第一个映射;
(2)表示CV_16SC2,CV_32FC1等
第四个参数:它有两种可能表示的对象:
(1)若map1表示点(x,y)时,这个参数不代表任何值;
(2)表示 CV_16UC1,CV_32FC1类型的Y值
第五个参数:插值方式,有四中插值方式:
(1)INTER_NEAREST——最近邻插值
(2)INTER_LINEAR——双线性插值(默认)
(3)INTER_CUBIC——双三样条插值(默认)
(4)INTER_LANCZOS4——lanczos插值(默认)
第六个参数:边界模式,默认BORDER_CONSTANT。
第七个参数:边界颜色,默认Scalar()黑色。
以下为函数应用及效果展示:

#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
	Mat srcImage = imread("D:\\visual studio 2010\\Projects\\remap\\1.jpg");
	Mat dstImage,map_x,map_y;
	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++)//rows:行
	{
		for(int i=0;i<srcImage.cols ;i++)
		{
			//改变map_x和map_y的值
			map_x.at<float>(j,i) = static_cast<float>(srcImage.rows -i);
			map_y.at<float>(j,i) = static_cast<float>( srcImage.rows-j);
		}
	}
	//进行重映射操作
	remap(srcImage,dstImage,map_x,map_y,CV_INTER_LINEAR,BORDER_CONSTANT,Scalar(255,0,0));
    //显示效果图
	imshow("效果图",dstImage);
	waitKey(0);
	return 0;
}

在这里插入图片描述
将第二个for循环修改为

for(int i=0;i<srcImage.cols ;i++)
		{
			//改变map_x和map_y的值
			//水平对称
			map_x.at<float>(j,i) = static_cast<float>( i);
			map_y.at<float>(j,i) = static_cast<float>( srcImage.rows-j);
		}

运行结果:
在这里插入图片描述
将第二个for循环修改为:

for(int i=0;i<srcImage.cols ;i++)
		{
			//改变map_x和map_y的值
			//垂直对称
			map_x.at<float>(j,i) = static_cast<float>(srcImage.rows -i);
			map_y.at<float>(j,i) = static_cast<float>(j);
		}

运行结果为:
在这里插入图片描述

### 关于 `remap` 函数 #### OpenCV 中的 `remap` 函数介绍 OpenCV 提供了一个名为 `remap()` 的函数用于实现图像的重映射操作。该函数允许通过指定两个映射表来定义源图中每个像素的新位置,从而完成复杂的几何变换[^2]。 具体来说,在调用此 API 后,程序会依据给定的地图文件(mapx 和 mapy),按照公式 \(dst(x,y)=src(mapx(x,y),mapy(x,y))\) 来重新排列原始图片上的每一个点的位置,并最终形成一张新的目标图片[^4]。 当执行这种类型的转换时,由于新旧坐标之间可能存在不完全匹配的情况,所以通常还需要采用某种形式的插值算法来估算那些不在整数坐标的像素颜色值;常用的有最近邻法(NN)、双线性(BILINEAR)以及三次样条(CUBIC)[^1]。 下面是具体的 C++ 实现例子: ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main(){ Mat image = imread("input.jpg"); // 加载输入图像 int width = image.cols; int height = image.rows; // 创建映射矩阵 Mat map_x(height, width, CV_32FC1); Mat map_y(height, width, CV_32FC1); for(int i=0; i<height; ++i){ for(int j=0; j<width; ++j){ float fx = static_cast<float>(j); float fy = static_cast<float>(i); // 这里可以自定义映射逻辑 map_x.at<float>(i,j) = fx * cos(PI / 4.f) - fy * sin(PI / 4.f); map_y.at<float>(i,j) = fx * sin(PI / 4.f) + fy * cos(PI / 4.f); } } Mat result; // 执行重映射操作 remap(image, result, map_x, map_y, INTER_LINEAR); imwrite("output.png",result); // 输出处理后的图像到磁盘上保存下来 } ``` 这段代码展示了如何创建一对浮点型单通道灰度级映射表格 (`map_x`, `map_y`) 并利用它们来进行一次简单的旋转效果模拟。注意这里只是简单地实现了顺时针方向45°角的旋转变换作为示范用途而已。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值