- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
将图像变换映射从一种表示形式转换为另一种表示形式。
该函数将用于 remap 的映射对从一种表示形式转换为另一种表示形式。以下选项 ((map1.type(), map2.type()) → (dstmap1.type(), dstmap2.type())) 是支持的:
- (CV_32FC1, CV_32FC1) → (CV_16SC2, CV_16UC1)。这是最常用的转换操作,其中原始的浮点数映射(见 remap)被转换为更紧凑且更快的固定点表示形式。第一个输出数组包含四舍五入的坐标,而第二个数组(仅在 nninterpolation=false 时创建)包含在插值表中的索引。
- (CV_32FC2) → (CV_16SC2, CV_16UC1)。与上述情况相同,但原始映射存储在一个双通道矩阵中。
- 反向转换。显然,重构的浮点数映射将不会完全与原始映射相同。
函数原型
void cv::convertMaps
(
InputArray map1,
InputArray map2,
OutputArray dstmap1,
OutputArray dstmap2,
int dstmap1type,
bool nninterpolation = false
)
参数
- 参数 map1 第一个输入映射,类型为 CV_16SC2、CV_32FC1 或 CV_32FC2。
- 参数map2 第二个输入映射,类型为 CV_16UC1、CV_32FC1 或为空(空矩阵),分别对应不同的输入映射类型。
- 参数dstmap1 第一个输出映射,具有类型 dstmap1type,并且与源映射 src 具有相同的尺寸。
- 参数dstmap2 第二个输出映射。
- 参数dstmap1type 第一个输出映射的类型,应为 CV_16SC2、CV_32FC1 或 CV_32FC2。
- 参数nninterpolation 标志,指示固定的点映射是否用于最近邻插值或更复杂的插值方法。
代码示例
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// 创建示例映射
Mat mapX = Mat::zeros(400, 600, CV_32FC1);
Mat mapY = Mat::zeros(400, 600, CV_32FC1);
// 初始化映射矩阵
for (int y = 0; y < mapX.rows; ++y)
{
for (int x = 0; x < mapX.cols; ++x)
{
mapX.at<float>(y, x) = x + 0.5f; // 示例:添加 0.5 的偏移
mapY.at<float>(y, x) = y - 0.5f; // 示例:减去 0.5 的偏移
}
}
// 转换映射
Mat mapX16s, mapY16s;
convertMaps(mapX, mapY, mapX16s, mapY16s, CV_16SC2);
// 使用转换后的映射进行图像重映射
Mat src = imread("/media/dingxin/data/study/OpenCV/sources/images/hawk.jpg");
cv::Size sz2Sh( 400, 600 );
cv::resize( src, src, sz2Sh, 0, 0, cv::INTER_LINEAR_EXACT );
Mat dst;
remap(src, dst, mapX16s, mapY16s, INTER_LINEAR);
// 显示结果
imshow("original", src);
imshow("Result", dst);
// 等待按键并关闭窗口
waitKey(0);
destroyAllWindows();
return 0;
}
运行结果
原始图:
结果图: