原理
图片重映射就是将图片中的像素从一个位置移动到另一个位置,从而形成新的图片。
要实现图片重映射,就有必要使用插值和非整数的像素位置,因此原图和结果图之间不可能总是存在像素的一一对应的。
用公式表示重映射的过程,如下:
g ( x , y ) = f ( h ( x , y ) ) g(x,y)=f(h(x,y)) g(x,y)=f(h(x,y))
- g ( x , y ) g(x,y) g(x,y)是重映射之后的结果图
- f ( ) f() f()是原图
- h ( x , y ) h(x,y) h(x,y)是在 ( x , y ) (x,y) (x,y)像素上的重映射操作
比如,对图片 I I I进行如下重映射操作:
h ( x , y ) = ( I . c o l s − x , y ) h(x,y)=(I.cols-x,y) h(x,y)=(I.cols−x,y)
通过用总列数减去当前列数,可以实现图片在 x x x方向的翻转,就像下面的2张图一样:


API
在OpenCV中,提供了专门的重映射方法cv::remap(),其函数原型如下:
void cv::remap( InputArray src,
OutputArray dst,
InputArray map1,
InputArray map2,
int interpolation,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar())
- 虽然该函数提供了
map1和map2两个map参数,但是可以只有map1用来提供 ( x , y ) (x,y) (x,y)两个方向上的重映射矩阵;或者map1提供 x x x上的重映射矩阵、而map2提供 y y y上的重映射矩阵;interpolation参数指定插值方法,包括:双线性插值(INTER_LINEAR)、双三次插值(INTER_CUBIC)、最近邻插值(INTER_NEARES)等;注意,在该函数中不能使用INTER_AREA, INTER_LINEAR_EXACT, INTER_NEAREST_EXACT,这3中插值方法borderMode为边框扩充方法,默认是BORDER_CONSTANT,即单一颜色边框;当该参数取BORDER_TRANSPARENT值的时候,表示重映射后超出原图范围的像素将不会被函数修改borderValue只有在borderMode = BORDER_CONSTANT的时候才需要提供,用来指定边框的颜色。
注意:该函数目前只支持小于 32767 × 32767 32767 \times 32767 32767×32767尺寸的输入图和输出图。
实现
重映射的关键就是建立映射矩阵。映射矩阵要和原图具有相同的尺寸:
//导入原图
Mat src{
imread("chicky_512.png", IMREAD_COLOR) };
Mat map_x(src.size(), CV_32FC1);//建立x方向上的空映射矩阵
Mat map_y(src.size(), CV_32FC1);//建立y方向上的空映射矩阵
接下来就是往映射矩阵里面填值了。
这个例子中我们分别建立下面4种重映射矩阵:
缩小成原来的一半并在中间显示
这种重映射的算法如下:
对于第 i i i列、第

最低0.47元/天 解锁文章
537

被折叠的 条评论
为什么被折叠?



