图像的坐标映射是通过原图像与目标图像之间建立一种映射关系,这种映射关系有两种,一种是计算原图像任意像素在映射后图像的坐标位置,另一种是计算变换后图像任意像素反映射在原图像的坐标位置。
opencv中提供重映射等操作,其中重映射就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。为了完成映射过程,需要获得一些插值为非整数像素的坐标。对于原图像和目标图像,满足下式:
G(x,y)=f(h(x,y))
G()是目标图像,f()是源图像,而h(x,y)是作用于(x,y)的映射方法函数。
函数原型如下:
Void remap(InputArray src,OutputArray dst,InputArray map1,InputArray map2,
int interpolation,int borderMode=BORDER_CONSTANT,const Scalar&borderValue=Scalar())
- src: 源图像
- dst: 目标图像,与 src 相同大小
- map1: x坐标
- map2: y坐标
- interpolation: 表示插值方法
- borderMode:表示边界插值类型
- borderValue:表示插值数值
实例代码如下:
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
int main()
{
cv::Mat srcImage = cv::imread("2.jpg");
if (!srcImage.data)
return -1;
//输出矩阵定义
cv::Mat resultImage(srcImage.size(), srcImage.type());
//x与y方向矩阵
cv::Mat xMapImage(srcImage.size(), CV_32FC1);
cv::Mat yMapImage(srcImage.size(), CV_32FC1);
//取图像的宽高
int rows = srcImage.rows;
int cols = srcImage.cols;
//图像遍历
for (int j = 0; j < rows; j++)
{
for (int i = 0; i < cols; i++)
{
//x与y均翻转
xMapImage.at<float>(j, i) = cols - i;
yMapImage.at<float>(j, i) = rows - j;
}
}
//重映射操作
remap(srcImage, resultImage, xMapImage, yMapImage, CV_INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0));
//输出结果
cv::imshow("srcImage", srcImage);
cv::imshow("resultImage", resultImage);
cv::waitKey(0);
return 0;
}
运行结果如下:
输入图像:
输出图像:
其中要注意图像遍历翻转时候的代码:
for (int j = 0; j < rows; j++)
{
for (int i = 0; i < cols; i++)
{
//x与y均翻转
xMapImage.at<float>(j, i) = cols - i;
yMapImage.at<float>(j, i) = rows - j;
}
}