opencv笔记(十九)——对图像进行remapping

何谓remapping呢?翻译过来就是重映射。因为每个图像本身就是f(x, y),是像素位置为自变量的像素值的函数。然后我们对这些位置上的像素的值再次进行变换,

g(x, y) = f(h(x, y)),h(x, y)就是重映射的函数,g(x, y)就是重映射的结果。

 

想象如果h(x, y) = f(I.cols-x, y),会怎么样?

明显地,新图像是原图像关于x轴的翻转。

 

先看看OpenCV中对remapping操作的定义

void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())

src是输入的图像,无特殊要求

dst是输出的图像,和src的尺寸类型一致。文档里说remap不能就地操作,建议dst最好不要与src相同。

map1是x轴上的映射,map1和src尺寸一致,类型一般为CV_32FC1。例如map1.at<float>(i, j) = (src.cols - i);

map2是y轴上的映射

interpolation在这里一般为INTER_LINEAR,采用bilinear interpolation方法将一对浮点坐标(映射后)转化为整数坐标。见下图:

 出自:http://en.wikipedia.org/wiki/Bilinear_interpolation

borderMode一般默认为BORDER_CONSTANT,这里的border我也不太清楚意义。

 

 

OpenCV给出的使用remap的例子很清晰易懂,注意map1和map2是如何设定的即可:

 1 /**
 2  * @function Remap_Demo.cpp
 3  * @brief Demo code for Remap
 4  * @author Ana Huaman
 5  */
 6 
 7 #include "opencv2/highgui/highgui.hpp"
 8 #include "opencv2/imgproc/imgproc.hpp"
 9 #include <iostream>
10 #include <stdio.h>
11 
12 using namespace cv;
13 
14 /// Global variables
15 Mat src, dst;
16 Mat map_x, map_y;
17 const char* remap_window = "Remap demo";
18 int ind = 0;
19 
20 /// Function Headers
21 void update_map( void );
22 
23 /**
24  * @function main
25  */
26 int main( int, char** argv )
27 {
28   /// Load the image
29   src = imread( argv[1], 1 );
30 
31   /// Create dst, map_x and map_y with the same size as src:
32   dst.create( src.size(), src.type() );
33   map_x.create( src.size(), CV_32FC1 );
34   map_y.create( src.size(), CV_32FC1 );
35 
36   /// Create window
37   namedWindow( remap_window, WINDOW_AUTOSIZE );
38 
39   /// Loop
40   for(;;)
41   {
42     /// Each 1 sec. Press ESC to exit the program
43     int c = waitKey( 1000 );
44 
45     if( (char)c == 27 )
46       { break; }
47 
48     /// Update map_x & map_y. Then apply remap
49     update_map();
50     remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0) );
51 
52     // Display results
53     imshow( remap_window, dst );
54   }
55   return 0;
56 }
57 
58 /**
59  * @function update_map
60  * @brief Fill the map_x and map_y matrices with 4 types of mappings
61  */
62 void update_map( void )
63 {
64   ind = ind%4;
65 
66   for( int j = 0; j < src.rows; j++ )
67     { for( int i = 0; i < src.cols; i++ )
68      {
69            switch( ind )
70          {
71          case 0:
72            if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 )
73                  {
74                map_x.at<float>(j,i) = 2*( i - src.cols*0.25f ) + 0.5f ;
75                map_y.at<float>(j,i) = 2*( j - src.rows*0.25f ) + 0.5f ;
76               }
77            else
78          { map_x.at<float>(j,i) = 0 ;
79                map_y.at<float>(j,i) = 0 ;
80                  }
81                    break;
82          case 1:
83                map_x.at<float>(j,i) = (float)i ;
84                map_y.at<float>(j,i) = (float)(src.rows - j) ;
85            break;
86              case 2:
87                map_x.at<float>(j,i) = (float)(src.cols - i) ;
88                map_y.at<float>(j,i) = (float)j ;
89            break;
90              case 3:
91                map_x.at<float>(j,i) = (float)(src.cols - i) ;
92                map_y.at<float>(j,i) = (float)(src.rows - j) ;
93            break;
94              } // end of switch
95      }
96     }
97   inqd++;
98 }
View Code

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。