OpenCV 图像重映射函数remap()实例详解

OpenCV 图像重映射函数remap()对图像应用通用几何变换。其原型如下:

void remap(InputArray src,

OutputArray dst,

InputArray map1,

InputArray map2,

int interpolation,

int borderMode = BORDER_CONSTANT,

const Scalar & borderValue = Scalar()

参数:

src 源图像。

dst 输出目标图像。它的大小与 map1 相同,类型与 src 相同。

map1 (x,y) 点或仅 x 值的第一个映射具有 CV_16SC2 、 CV_32FC1 或 CV_32FC2 类型。

map2 y 值的第二个映射分别具有 CV_16UC1、CV_32FC1 类型或无类型(如果映射 1 是 (x,y) 点,则为空映射)。

interpolation 插值方法,可选: INTER_NEAREST, INTER_LINEAR , INTER_CUBIC, INTER_LANCZOS4, INTER_NEAREST_EXACT INTER_MAX WARP_FILL_OUTLIERS , WARP_INVERSE_MAP

borderMode 像素外推法。当 borderMode=BORDER_TRANSPARENT 时,意味 着目标图像中与源图像中的"异常值"相对应的像素不会被该函数修改。可为:BORDER_CONSTANT ,BORDER_REPLICATE,BORDER_REFLECT,BORDER_WRAP ,BORDER_REFLECT_101 ,BORDER_TRANSPARENT ,BORDER_REFLECT101 ,BORDER_DEFAULT,BORDER_ISOLATED

borderValue 在边界恒定的情况下使用的值。默认值为 0。

OpenCV的remap函数的主要用途是重新映射图像中像素的位置或值。用它可以实现图像镜像、形态改变、特效制作、图像分割等。下面以例演示 其用法。先写一个示例程序,读入一张图片然后,用remap函数分别获取水平镜像图片,示例程序代码如下:

复制代码
// RemapTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

#include<opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
	Mat src = imread("1.png");
	if (src.empty())
	{
		cout << "Cann't load Image!";
		return -1;
	}
	imshow("原始图像:",src);
	Mat srcx(src.rows, src.cols, CV_32F); // x 方向
	Mat srcy(src.rows, src.cols, CV_32F); // y 方向

	for (size_t i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			srcx.at<float>(i, j) = src.cols - j - 1;
			srcy.at<float>(i, j) = i;
			
		}
	}
	remap(src, src, srcx, srcy, INTER_LINEAR);
	imshow("水平镜像:", src);

	waitKey(0);
	return 1;
}

试运行,结果如下:

获取垂直镜像,其代码如下:

复制代码
// RemapTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

#include<opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
	Mat src = imread("1.png");
	if (src.empty())
	{
		cout << "Cann't load Image!";
		return -1;
	}
	imshow("原始图像:",src);
	Mat srcx(src.rows, src.cols, CV_32F); // x 方向
	Mat srcy(src.rows, src.cols, CV_32F); // y 方向

	//水平镜像
	/*
	for (size_t i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			srcx.at<float>(i, j) = src.cols - j - 1;
			srcy.at<float>(i, j) = i;
			
		}
	}
	remap(src, src, srcx, srcy, INTER_LINEAR);
	imshow("水平镜像:", src);
	*/

	//垂直镜像
	for (size_t i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			srcx.at<float>(i, j) = j;
			srcy.at<float>(i, j) = src.rows -i -1;

		}
	}
	remap(src, src, srcx, srcy, INTER_LINEAR);
	imshow("垂直镜像:", src);

	waitKey(0);
	return 1;
}

试运行结果如下:

再写一段改变图形形状的代码,代码如下:

复制代码
// RemapTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

#include<opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
	Mat src = imread("1.png");
	if (src.empty())
	{
		cout << "Cann't load Image!";
		return -1;
	}
	imshow("原始图像:",src);
	Mat srcx(src.rows, src.cols, CV_32F); // x 方向
	Mat srcy(src.rows, src.cols, CV_32F); // y 方向

	//水平镜像
	/*
	for (size_t i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			srcx.at<float>(i, j) = src.cols - j - 1;
			srcy.at<float>(i, j) = i;
			
		}
	}
	remap(src, src, srcx, srcy, INTER_LINEAR);
	imshow("水平镜像:", src);
	*/

	//垂直镜像
	/*
	for (size_t i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			srcx.at<float>(i, j) = j;
			srcy.at<float>(i, j) = src.rows -i -1;

		}
	}
	remap(src, src, srcx, srcy, INTER_LINEAR);
	imshow("垂直镜像:", src);
	*/

	//改变图像形状
	for (size_t i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			srcx.at<float>(i, j) = j;
			srcy.at<float>(i, j) = i + 5.0 * cos(i / 5.0);
		}
	}
	remap(src, src, srcx, srcy, INTER_LINEAR);
	imshow("改变图形形状:", src);



	waitKey(0);
	return 1;
}

割裂效果呈现,实现的程序代码如下:

复制代码
// RemapTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

#include<opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
	Mat src = imread("1.png");
	if (src.empty())
	{
		cout << "Cann't load Image!";
		return -1;
	}
	imshow("原始图像:",src);
	Mat srcx(src.rows, src.cols, CV_32F); // x 方向
	Mat srcy(src.rows, src.cols, CV_32F); // y 方向

	//水平镜像
	/*
	for (size_t i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			srcx.at<float>(i, j) = src.cols - j - 1;
			srcy.at<float>(i, j) = i;
			
		}
	}
	remap(src, src, srcx, srcy, INTER_LINEAR);
	imshow("水平镜像:", src);
	*/

	//垂直镜像
	/*
	for (size_t i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			srcx.at<float>(i, j) = j;
			srcy.at<float>(i, j) = src.rows -i -1;

		}
	}
	remap(src, src, srcx, srcy, INTER_LINEAR);
	imshow("垂直镜像:", src);
	*/

	//改变图像形状
	/*
	for (size_t i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			srcx.at<float>(i, j) = j;
			srcy.at<float>(i, j) = i + 5.0 * cos(i / 5.0);
		}
	}
	remap(src, src, srcx, srcy, INTER_LINEAR);
	imshow("改变图形形状:", src);
	*/

	//割裂效果呈现
	for (size_t i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			srcx.at<float>(i, j) = j + 10.0 * tan(j / 5.0);;
			srcy.at<float>(i, j) = i;
		}
	}
	remap(src, src, srcx, srcy, INTER_LINEAR);
	imshow("割裂效果:", src);


	waitKey(0);
	return 1;
}

试运行,结果如下:

相关推荐
闭关修炼啊哈2 分钟前
[IdeaLoop · 灵感回路] AI时代独立开发者·创业/副业灵感日报 · 2026-05-17
人工智能·远程工作·创业·副业
赢乐39 分钟前
大模型学习笔记:检索增强生成(RAG)架构
人工智能·python·深度学习·机器学习·智能体·幻觉·检索增强生成(rag)
飞哥数智坊1 小时前
OPC 需要的不是一个个AI工具,而是一支数字团队
人工智能
小橙讲编程1 小时前
200+ 模型、零内容过滤、完全免费 — Open Generative AI 全面解析与实战指南
人工智能
happyprince2 小时前
Hugging Face Transformers 源码全景解读
人工智能
春风LiuK2 小时前
远程服务器安装 Claude Code 并配置 DeepSeek v4
人工智能
冬奇Lab2 小时前
RAG 系列(二十):企业级 RAG 架构设计
人工智能·llm
冬奇Lab2 小时前
一天一个开源项目(第104篇):CLI-Anything - 让所有软件变成 AI 代理可调用的命令行接口
人工智能·开源·资讯
冬奇Lab2 小时前
RAG 系列(十九):增量更新——知识库如何保持新鲜
人工智能·llm
浪里行舟3 小时前
你的品牌正在被AI“遗忘”?用BuildSOM找回搜索的下一个风口
人工智能·python·程序员