opencv 图像处理 重映射 remap()

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-31 22:14   123   0

重映射

重映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。为了完成映射过程,需要获得一些插值为非整数像素的坐标,因为原图像与目标图像的像素坐标不是一一对应的。 一般情况下,我们通过重映射来表达每个像素的 位置(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)操作。看看其原型和参数。

void cv::remap(InputArray src,
OutputArray dst,
InputArray map1,
InputArray map2,
int interpolation,
int borderMode = BORDER_CONSTANT,
const Scalar & borderValue = Scalar()
)
Python:
dst=cv.remap(src, map1, map2, interpolation[, dst[, borderMode[, borderValue]]])

#include <opencv2/imgproc.hpp>

Parameters

srcSource image.
dstDestination image. It has the same size as map1 and the same type as src .
map1The 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.
map2The second map of y values having the type CV_16UC1, CV_32FC1, or none (empty map if map1 is (x,y) points), respectively.
interpolationInterpolation method (see InterpolationFlags). The method INTER_AREA is not supported by this function.
borderModePixel 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.
borderValueValue 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;
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP