Image Processing16(Remapping )

Goal

In this tutorial you will learn how to:

a. Use the OpenCV function cv::remap to implement simple remapping routines.

a.使用OpenCV函数cv::remap进行图像的重映射。

Theory

What is remapping?

It is the process of taking pixels from one place in the image and locating them in another position in a new image.

把图像中的一个像素定位到新的图像中的另外一个位置。

To accomplish the mapping process, it might be necessary to do some interpolation for non-integer pixel locations, since there will not always be a one-to-one-pixel correspondence between source and destination images.

为了完成映射过程,可能需要非整数的像素位置进行插值,由于源图像和目标图像可能不是一一对应的关系。

We can express the remap for every pixel location (x,y) as:

g(x,y)=f(h(x,y))

where g() is the remapped image, f() the source image and h(x,y) is the mapping function that operates on (x,y).

g()是映射后的图像,f()是原图像,h(x,y)是映射变换函数。

Let's think in a quick example. Imagine that we have an image I and, say, we want to do a remap such that:

h(x,y)=(I.colsx,y)
一个简单例子如下,有一个图像为I,进行如下的变换:

What would happen? It is easily seen that the image would flip in the x direction. For instance, consider the input image:

                                                                          Remap_Tutorial_Theory_0.jpg

可以轻易的看处理,图像在X方向进行了对调。

  • observe how the red circle changes positions with respect to x (considering x the horizontal direction):

                                                                      Remap_Tutorial_Theory_1.jpg
  • In OpenCV, the function  cv::map offers a simple remapping implementation.
  • 在OpenCV中,函数:cv::map可以实现这个功能。

Code

  1. What does this program do?
    • Loads an image(加载图像)
    • Each second, apply 1 of 4 different remapping processes to the image and display them indefinitely in a window.(没过1秒,进行四种重映射过程)
    • Wait for the user to exit the program(等待用户退出)
  2. The tutorial code's is shown lines below. You can also download it from here

Code

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
Mat src, dst;
Mat map_x, map_y;
const char* remap_window = "Remap demo";
int ind = 0;
void update_map( void );
int main(int argc, const char** argv)
{
  CommandLineParser parser(argc, argv, "{@image |lena.jpg|input image name}");
  std::string filename = parser.get<std::string>(0);
  src = imread( filename, IMREAD_COLOR );
  dst.create( src.size(), src.type() );
  map_x.create( src.size(), CV_32FC1 );//CV_32FC1因为就一个数据。
  map_y.create( src.size(), CV_32FC1 );//CV_32FC1因为就一个数据。
  namedWindow( remap_window, WINDOW_AUTOSIZE );
  for(;;)
  {
    char c = (char)waitKey( 1000 );
    if( c == 27 )
      { break; }
    update_map();//更新映射函数
    remap( src, dst, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0) );
    //输入,输出,X方向上的映射函数,Y方向上的映射函数,插值类型,边框,值
    // Display results

    imshow( remap_window, dst );
  }
  return 0;
}
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.25f ) + 0.5f ;
               map_y.at<float>(j,i) = 2*( j - src.rows*0.25f ) + 0.5f ;
              }
           else
                { map_x.at<float>(j,i) = 0 ;
                  map_y.at<float>(j,i) = 0 ;
                 }
                   break;
         case 1:
               map_x.at<float>(j,i) = (float)i ;
               map_y.at<float>(j,i) = (float)(src.rows - j) ;
           break;
         case 2:
               map_x.at<float>(j,i) = (float)(src.cols - i) ;
               map_y.at<float>(j,i) = (float)j ;
           break;
         case 3:
               map_x.at<float>(j,i) = (float)(src.cols - i) ;
               map_y.at<float>(j,i) = (float)(src.rows - j) ;
           break;
             } // end of switch
     }
    }
  ind++;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

set(CMAKE_CXX_FLAGS "-std=c++11")
project( DisplayImage )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( DisplayImage main.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )


install(TARGETS DisplayImage RUNTIME DESTINATION bin

Results



猜你喜欢

转载自blog.csdn.net/qq_27806947/article/details/80304974