1. 程式人生 > >opencv圖片全景拼接詳解

opencv圖片全景拼接詳解

簡介
基本的拼接方式參見: 《opencv實現影象的拼接功能》 
本博文基於取景模式講解影象拼接。API全面基本的介紹介紹參見:

  opencv官網:http://docs.opencv.org/modules/stitching/doc/stitching.html
在opencv原始碼中stitching.cpp 是簡單版影象拼接例項,參見《opencv實現影象的拼接功能》。
stitching_detailed.cpp 複雜全面版影象拼接例項。

簡單例項(stitching.cpp)

  首先看下,opencv實現影象拼接的最簡單例項,這是將stitching.cpp裁剪到最簡單的程式碼

具體精簡程式碼如下:

#include <iostream>  
#include <fstream>  
#include "opencv2/highgui/highgui.hpp"  
#include "opencv2/stitching/stitcher.hpp"  
   
using namespace std;  
using namespace cv;  
   
bool try_use_gpu = true; //false;  
vector<Mat> imgs;  
string result_name = "result.jpg";  
   
int parseCmdArgs(int argc, char** argv)
{  
    for (int i = 1; i < argc; ++i){  
        Mat img = imread(argv[i]);  
        if (img.empty()){  
            cout << "Can't read image '" << argv[i] << "'\n";  
            return -1;  
        }  
        imgs.push_back(img);  
        imshow(argv[i], img);  
    }  
    return 0;  
}  
   
int main(int argc, char* argv[])
{  
    int retval = parseCmdArgs(argc, argv);  
    if (retval) return -1;  
   
    Mat pano;  
    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);  
    Stitcher::Status status = stitcher.stitch(imgs, pano);

   
    if (status != Stitcher::OK)
    {  
        cout << "Can't stitch images, error code = " << int(status) << endl;  
        return -1;  
    }  
   
    imwrite(result_name, pano);  
    imshow("show", pano);  
    cv::waitKey(0);  
    return 0;  
}

效果演示

  


 基於不同模式的全景拼接(stitching_detailed.cpp精簡版)



程式碼具體程式碼如下:

#include <iostream>  
#include <fstream>  
#include "opencv2/highgui/highgui.hpp"  
#include "opencv2/stitching/stitcher.hpp"  
   
using namespace std;  
using namespace cv;  
   
bool try_use_gpu = false;  
vector<Mat> imgs;  
string result_name = "result.jpg";  
   
int parseCmdArgs(int argc, char** argv)
//輸入的圖片全部填充到容器imgs中,並將輸入的圖片顯示出來。
    for (int i = 1; i < argc-1; ++i)
    {  
        Mat img = imread(argv[i]);  
        if (img.empty()){  
            cout << "Can't read image '" << argv[i] << "'\n";  
            return -1;  
        }  
        imgs.push_back(img);  
   
        imshow(argv[i], img);  
    }  
    return 0;  
}  
   
int main(int argc, char* argv[])
{  
    int retval = parseCmdArgs(argc, argv);  
    if (retval) return -1;  
   
    Mat pano;        
    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);  //建立一個stitcher物件。
   
    if(argv[4][0] == '1')
    {  //1:平面拼接
        PlaneWarper* cw = new PlaneWarper();  
        stitcher.setWarper(cw);  
    }
    else if(argv[4][0] == '2')
    {//2:柱面 拼接
        SphericalWarper* cw = new SphericalWarper();      
        stitcher.setWarper(cw);  
    }
    else if(argv[4][0] == '3')
    {//3:立體畫面拼接
        StereographicWarper *cw = new cv::StereographicWarper();      
        stitcher.setWarper(cw);  
    }  
   
    //使用Surf演算法來尋找特徵點,支援Surf和Orb兩種方式
    detail::SurfFeaturesFinder *featureFinder = new detail::SurfFeaturesFinder();  
    stitcher.setFeaturesFinder(featureFinder);  
   
    /*匹配給定的影象和估計相機的旋轉*/  
    Stitcher::Status status = stitcher.estimateTransform(imgs);  //另一種方式來實現拼接
    if (status != Stitcher::OK)  
    {  
        cout << "Can't stitch images, error code = " << int(status) << endl;  
        return -1;  
    }  
   
    /*生成全景影象*/  
    status = stitcher.composePanorama(pano);  
    if (status != Stitcher::OK)  
    {  
        cout << "Can't stitch images, error code = " << int(status) << endl;  
        return -1;  
    }  
   
    imwrite(result_name, pano);  
    imshow("show", pano);  
    cv::waitKey(0);  
    return 0;  



程式碼中設定生成結果圖為:1:平面, 2:柱面, 3:立體畫面。在它提供的複雜版例項:stitching_detailed.cpp,
有如下種類可以選擇:
plane|cylindrical|spherical|fisheye|stereographic|compressedPlaneA2B1|
compressedPlaneA1.5B1|compressedPlanePortraitA2B1|compressedPlanePortraitA1.5B1|paniniA2B1|
paniniA1.5B1|paniniPortraitA2B1|paniniPortraitA1.5B1|mercator|transverseMercator

本例中結果展示: 
1:平面

2:柱面

3:立體畫面