重映射
重映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。为了完成映射过程,需要获得一些插值为非整数像素的坐标,因为原图像与目标图像的像素坐标不是一一对应的。 一般情况下,我们通过重映射来表达每个像素的 位置(x,y),像这样:
g(x,y)=f(h(x,y))
在这里g()是目标图像,f()是源图像,而h(x,y)的映射方法函数。
来看个例子。 若有一幅图像I,对其按照下面条件作重映射:
h(x,y)=(I.cols-x,y)
图像会按照x轴方向发生翻转。
 
在OpenCV中,我们用函数remap( )来实现简单重映射,下面我们就一起来看看这个函数。
remap( )函数解析
remap( )函数会根据我们指定的映射形式,将源图像进行重映射几何变换,基于的式子如下:

需要注意,此函数不支持就地(in-place)操作。看看其原型和参数。
| Python: |
|---|
| | dst | = | cv.remap( | src, map1, map2, interpolation[, dst[, borderMode[, borderValue]]] | ) |
#include <opencv2/imgproc.hpp>
Parameters
| src | Source image. | | dst | Destination image. It has the same size as map1 and the same type as src . | | map1 | The first map of either (x,y) points or just x values having the type CV_16SC2 , CV_32FC1, or CV_32FC2. See convertMaps for details on converting a floating point representation to fixed-point for speed. | | map2 | The second map of y values having the type CV_16UC1, CV_32FC1, or none (empty map if map1 is (x,y) points), respectively. | | interpolation | Interpolation method (see InterpolationFlags). The method INTER_AREA is not supported by this function. | | borderMode | Pixel extrapolation method (see BorderTypes). When borderMode=BORDER_TRANSPARENT, it means that the pixels in the destination image that corresponds to the "outliers" in the source image are not modified by the function. | | borderValue | Value used in case of a constant border. By default, it is 0. |
附:
#include <opencv2/imgproc.hpp>
interpolation algorithm
| Enumerator |
|---|
| INTER_NEAREST Python: cv.INTER_NEAREST | nearest neighbor interpolation | | INTER_LINEAR Python: cv.INTER_LINEAR | bilinear interpolation | | INTER_CUBIC Python: cv.INTER_CUBIC | bicubic interpolation | | INTER_AREA Python: cv.INTER_AREA | resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method. | | INTER_LANCZOS4 Python: cv.INTER_LANCZOS4 | Lanczos interpolation over 8x8 neighborhood | | INTER_LINEAR_EXACT Python: cv.INTER_LINEAR_EXACT | Bit exact bilinear interpolation | | INTER_MAX Python: cv.INTER_MAX | mask for interpolation codes | | WARP_FILL_OUTLIERS Python: cv.WARP_FILL_OUTLIERS | flag, fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero | | WARP_INVERSE_MAP Python: cv.WARP_INVERSE_MAP | flag, inverse transformation For example, linearPolar or logPolar transforms:
- flag is not set: dst(ρ,)=src(x,y)
- flag is set: dst(x,y)=src(ρ,)
|
下面放出精简后的以remap函数为核心的示例程序,方便大家快速掌握remap函数的使用方法。
//-----------------------------------【程序说明】----------------------------------------------
// 程序名称::《【OpenCV入门教程之十七】OpenCV重映射 & SURF特征点检测合辑 》 博文配套源码
// 开发所用IDE版本:Visual Studio 2010
// 开发所用OpenCV版本: 2.4.9
// 2014年5月26日 Created by 浅墨
// 配套博文链接: http://blog.csdn.net/poem_qianmo/article/details/26977557
// PS:程序结合配合博文学习效果更佳
// 浅墨的微博:@浅墨_毛星云 http://weibo.com/1723155442
// 浅墨的知乎:http://www.zhihu.com/people/mao-xing-yun
// 浅墨的豆瓣:http://www.douban.com/people/53426472/
//----------------------------------------------------------------------------------------------
//-----------------------------------【头文件包含部分】---------------------------------------
// 描述:包含程序所依赖的头文件
//----------------------------------------------------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
//-----------------------------------【命名空间声明部分】--------------------------------------
// 描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace cv;
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( )
{
//【0】变量定义
Mat srcImage, dstImage;
Mat map_x, map_y;
//【1】载入原始图
srcImage = imread( "1.jpg", 1 );
if(!srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
imshow("原始图",srcImage);
//【2】创建和原始图一样的效果图,x重映射图,y重映射图
dstImage.create( srcImage.size(), srcImage.type() );
map_x.create( srcImage.size(), CV_32FC1 );
map_y.create( srcImage.size(), CV_32FC1 );
//【3】双层循环,遍历每一个像素点,改变map_x & map_y的值
for( int j = 0; j < srcImage.rows;j++)
{
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);
}
}
//【4】进行重映射操作
remap( srcImage, dstImage, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) );
//【5】显示效果图
imshow( "【程序窗口】", dstImage );
waitKey();
return 0;
}

|