目錄
1.1目標
展示如何使用OpenCV函數 remap 來實現簡單重映射.
1.2 理論
-
把一個圖像中一個位置的像素放置到另一個圖片指定位置的過程.
-
爲了完成映射過程, 有必要獲得一些插值爲非整數像素座標,因爲源圖像與目標圖像的像素座標不是一一對應的.
-
我們通過重映射來表達每個像素的位置 :
這裏 是目標圖像, 是源圖像, 是作用於 的映射方法函數.
-
讓我們來思考一個快速的例子. 想象一下我們有一個圖像 , 我們想滿足下面的條件作重映射:
會發生什麼? 圖像會按照 軸方向發生翻轉. 例如, 源圖像如下:
看到紅色圈關於 x 的位置改變( 軸水平翻轉):
-
通過 OpenCV 的函數 remap 提供一個簡單的重映射實現.
1.3 代碼
-
本程序做什麼?
-
裝載一幅圖像.
-
程序按秒循環, 在一個窗口中順序出現4種重映射過程對相同的圖像.
-
等待用戶按 ‘ESC’ 鍵退出程序。
-
-
下面是本教程代碼. 你也可以從 這裏 下載。
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
/// Global variables
Mat src, dst;
Mat map_x, map_y;
char* remap_window = "Remap demo";
int ind = 0;
/// Function Headers
void update_map( void );
/**
* @function main
*/
int main( int argc, char** argv )
{
/// Load the image
src = imread( argv[1], 1 );
/// Create dst, map_x and map_y with the same size as src:
dst.create( src.size(), src.type() );
map_x.create( src.size(), CV_32FC1 );
map_y.create( src.size(), CV_32FC1 );
/// Create window
namedWindow( remap_window, CV_WINDOW_AUTOSIZE );
/// Loop
while( true )
{
/// Each 1 sec. Press ESC to exit the program
int c = waitKey( 1000 );
if( (char)c == 27 )
{ break; }
/// Update map_x & map_y. Then apply remap
update_map();
remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) );
/// Display results
imshow( remap_window, dst );
}
return 0;
}
/**
* @function update_map
* @brief Fill the map_x and map_y matrices with 4 types of mappings
*/
void update_map( void )
{
ind = ind%4;
for( int j = 0; j < src.rows; j++ )
{ for( int i = 0; i < src.cols; i++ )
{
switch( ind )
{
case 0:
if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 )
{
map_x.at<float>(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ;
map_y.at<float>(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ;
}
else
{ map_x.at<float>(j,i) = 0 ;
map_y.at<float>(j,i) = 0 ;
}
break;
case 1:
map_x.at<float>(j,i) = i ;
map_y.at<float>(j,i) = src.rows - j ;
break;
case 2:
map_x.at<float>(j,i) = src.cols - i ;
map_y.at<float>(j,i) = j ;
break;
case 3:
map_x.at<float>(j,i) = src.cols - i ;
map_y.at<float>(j,i) = src.rows - j ;
break;
} // end of switch
}
}
ind++;
}
1.4 運行結果