概念
什么是重映射?
这是从图像中的一个位置获取像素并将它们定位到新图像中的另一个位置的过程。
为了完成映射过程,可能需要对非整数像素位置进行一些插值,因为源图像和目标图像之间并不总是存在一对一的像素对应关系。
我们可以表达每个像素位置的重映射( x , y)作为:
其中g()是映射的图像,f()是源图像,h(x,y)是作用于(x,y)的映射函数。
opencv 函数支持 cv::remap()
1.函数原型:
CV_EXPORTS_W void remap( InputArray src, OutputArray dst,
InputArray map1, InputArray map2,
int interpolation, int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());
2.参数说明
src:源图像。
dst:目标图像。 它的大小与map1相同,类型与src相同。
map1:map1存放的时x的坐标值,有类型 CV_16SC2 ,
CV_32FC1, or CV_32FC2
CV_32FC1或CV_32FC2。 有关浮点数转换的详细信息,请参阅convertMaps
表示到定点的速度。
map2:map2存放的是y的坐标值,有类型 CV_16SC2 ,
CV_32FC1, or CV_32FC2
interpolation:插值方法(参见#InterpolationFlags)。 方法#INTER_AREA是
此函数不支持。
borderMode:像素外推方法(参见#BorderTypes) 当
borderMode:边界处理模式
borderValue:用于边界的值。 缺省值是0。
测试代码:
cv::Mat src;
src = cv::imread("D:\\QtProject\\Opencv_Example\\remap\\remap.png", cv::IMREAD_GRAYSCALE);
if (src.empty()) {
cout << "matTemplate Cannot load image" << endl;
return;
}
cv::imshow("src", src);
cv::Mat dstUpDown(src.size(), src.type());
cv::Mat map_x(src.size(), CV_32FC1);
cv::Mat map_y(src.size(), CV_32FC1);
//上下镜像
for( int i = 0; i < map_x.rows; i++ )
{
for( int j = 0; j < map_x.cols; j++ )
{
map_x.at<float>(i, j) = (float)j;
map_y.at<float>(i, j) = (float)(map_x.rows - i);
}
}
cv::remap( src, dstUpDown, map_x, map_y, cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar(0));
cv::imshow("dstUpDown", dstUpDown);
//左右镜像
for( int i = 0; i < map_x.rows; i++ )
{
for( int j = 0; j < map_x.cols; j++ )
{
map_x.at<float>(i, j) = (float)(map_x.cols - j);
map_y.at<float>(i, j) = (float)i;
}
}
cv::Mat dstLeftRight(src.size(), src.type());
cv::remap( src, dstLeftRight, map_x, map_y, cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar(0));
cv::imshow("dstLeftRight", dstLeftRight);
程序运行效果:
上下镜像:
左右镜像