imgproc模塊--Remapping重映射

1.目的
(1)如何使用openCV函數remap實現簡單的重映射

2.原理
把一個圖像中一個位置的像素放置到另一個圖片指定位置的過程,爲了完成映射過程, 有必要獲得一些插值爲非整數像素座標,因爲源圖像與目標圖像的像素座標不是一一對應的。我們通過重映射來表達每個像素的位置(x,y):

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

這裏 g 是目標圖像, f 是源圖像, h(x,y) 是作用於 (x,y) 的映射方法函數。

3.部分代碼解釋
(1)remap

    /*
    Remapping參數解釋
    src:輸入圖像
    dst:輸出圖像
    map_x:表示點(x,y)的x映射,CV_32FC1或者CV_16SC2類型
    map_y:表示點(x,y)的y映射,CV_32FC1或者CV_16SC2類型
    CV_INTER_LINEAR:非整數插值類型,
        包括四個:CV_INTER_LINEAR:雙線性插值,
                  CV_INTER_CUBIC:三樣條插值,
                  CV_INTER_NEAREST:最近臨插值,
                  CV_INTER_LANCZOS4:lanczos插值(默認)
    BORDER_CONSTANT:默認邊界
    Scalar(0,0,0):邊界顏色,默認爲黑色
    */
    remap(src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0,0));

4.完整代碼
(1)CommonInclude.h

#ifndef COMMON_INCLUDE
#define COMMON_INCLUDE
#include<iostream>
using namespace std;
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
#endif

(2)Remapping.cpp

#include"CommonInclude.h"

int type = 0;
int max_type = 3;
Mat src, dst;
Mat map_x, map_y;
char windowName[] = "Remapping";

void Mapping(int, void*){
    for(int x=0; x<src.rows; x++){
        for(int y=0; y<src.cols; y++){
            switch(type){
                case(0):
                    if(x>src.rows/4.0 && x < src.rows*3.0/4.0 && y>src.cols/4.0 && y < src.cols*3.0/4.0){
                        map_x.at<float>(x,y) = 2*(x - src.rows/4.0) + 0.5;
                        map_y.at<float>(x,y) = 2*(y - src.cols/4.0) + 0.5;
                    }
                    //縮放一倍數
                    break;
                case(1):
                    //左右翻轉
                    map_x.at<float>(x,y) = src.cols - x;
                    map_y.at<float>(x,y) = y;
                    break;
                case(2):
                    //上下翻轉
                    map_x.at<float>(x,y) = x;
                    map_y.at<float>(x,y) = src.rows - y;
                    break;
                case(3):
                    //中心對稱翻轉
                    map_x.at<float>(x,y) = src.cols - x;
                    map_y.at<float>(x,y) = src.rows - y;
                    break;
                default:
                    cout << "error type!!!" << endl;
                    break;
            }           
        }
    }
    //remapping重新映射
    /*
    Remapping參數解釋
    src:輸入圖像
    dst:輸出圖像
    map_x:表示點(x,y)的x映射,CV_32FC1或者CV_16SC2類型
    map_y:表示點(x,y)的y映射,CV_32FC1或者CV_16SC2類型
    CV_INTER_LINEAR:非整數插值類型,
        包括四個:CV_INTER_LINEAR:雙線性插值,
                  CV_INTER_CUBIC:三樣條插值,
                  CV_INTER_NEAREST:最近臨插值,
                  CV_INTER_LANCZOS4:lanczos插值(默認)
    BORDER_CONSTANT:默認邊界
    Scalar(0,0,0):邊界顏色,默認爲黑色
    */
    remap(src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0,0));
    imshow(windowName, dst);
}

int main(int argc, char** argv){
    if(argc < 2){
        cout << "more parameters are required!!!" << endl;
        return(-1);
    }
    src = imread(argv[1]);
    if(!src.data){
        cout << "error to read image!!!" << endl;
        return(-1);
    }
    //dst.create(src.size(), src.type());
    map_x.create(src.size(), CV_32FC1);
    map_y.create(src.size(), CV_32FC1);
    namedWindow(windowName, CV_WINDOW_AUTOSIZE);
    cout << src.size() << endl;
    //cvtColor(src, src, CV_BGR2GRAY);
    //cout << src.size() << endl;
    createTrackbar("Type:\n0:縮放一倍\n1:左右翻轉\n2:上下翻轉\n3:中心對稱翻轉", windowName,
            &type, max_type,
            Mapping);
    Mapping(0,0);
    waitKey(0);
    return(0);
}

參考文獻
1.http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/remap/remap.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章