zoukankan      html  css  js  c++  java
  • 关于OpenCV的stitching使用

    配置环境:VS2010+OpenCV2.4.9

    为了使用OpenCV实现图像拼接头痛了好长时间,一直都没时间做,今天下定决心去实现基本的图像拼接。

    首先,看一看使用OpenCV进行拼接的方法

    基本都是用Stitcher类中的stitch方法。下面是网上的代码,同时也是opencvsamplescppstitching.cpp的代码。

     1 #include <iostream>
     2 #include <fstream>
     3 #include "opencv2/highgui/highgui.hpp"
     4 #include "opencv2/stitching/stitcher.hpp"
     5  
     6 using namespace std;
     7 using namespace cv;
     8  
     9 bool try_use_gpu = false;
    10 vector<Mat> imgs;
    11 string result_name = "result.jpg";
    12  
    13 void printUsage();
    14 int parseCmdArgs(int argc, char** argv);
    15  
    16 int main(int argc, char* argv[])
    17 {
    18     int retval = parseCmdArgs(argc, argv);
    19     if (retval) return -1;
    20  
    21     Mat pano;
    22     Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    23     Stitcher::Status status = stitcher.stitch(imgs, pano);
    24  
    25     if (status != Stitcher::OK)
    26     {
    27         cout << "Can't stitch images, error code = " << int(status) << endl;
    28         return -1;
    29     }
    30  
    31     imwrite(result_name, pano);
    32     return 0;
    33 }
    34  
    35  
    36 void printUsage()
    37 {
    38     cout <<
    39         "Rotation model images stitcher.
    
    "
    40         "stitching img1 img2 [...imgN]
    
    "
    41         "Flags:
    "
    42         "  --try_use_gpu (yes|no)
    "
    43         "      Try to use GPU. The default value is 'no'. All default values
    "
    44         "      are for CPU mode.
    "
    45         "  --output <result_img>
    "
    46         "      The default is 'result.jpg'.
    ";
    47 }
    48  
    49  
    50 int parseCmdArgs(int argc, char** argv)
    51 {
    52     if (argc == 1)
    53     {
    54         printUsage();
    55         return -1;
    56     }
    57     for (int i = 1; i < argc; ++i)
    58     {
    59         if (string(argv[i]) == "--help" || string(argv[i]) == "/?")
    60         {
    61             printUsage();
    62             return -1;
    63         }
    64         else if (string(argv[i]) == "--try_use_gpu")
    65         {
    66             if (string(argv[i + 1]) == "no")
    67                 try_use_gpu = false;
    68             else if (string(argv[i + 1]) == "yes")
    69                 try_use_gpu = true;
    70             else
    71             {
    72                 cout << "Bad --try_use_gpu flag value
    ";
    73                 return -1;
    74             }
    75             i++;
    76         }
    77         else if (string(argv[i]) == "--output")
    78         {
    79             result_name = argv[i + 1];
    80             i++;
    81         }
    82         else
    83         {
    84             Mat img = imread(argv[i]);
    85             if (img.empty())
    86             {
    87                 cout << "Can't read image '" << argv[i] << "'
    ";
    88                 return -1;
    89             }
    90             imgs.push_back(img);
    91         }
    92     }
    93     return 0;
    94 }
       

     感觉这个说的比较繁琐,我就改写成了下面的代码

     1 #include <iostream>
     2 #include <fstream>
     3 #include <opencv2/core/core.hpp>
     4 #include "opencv2/highgui/highgui.hpp"
     5 #include "opencv2/stitching/stitcher.hpp"
     6 #include<Windows.h>
     7  
     8 using namespace std;
     9 using namespace cv;
    10  
    11 bool try_use_gpu = false;
    12 vector<Mat> imgs;
    13 string result_name = "result.jpg";
    14  
    15 int main()
    16 {
    17     Mat img1=imread("1.jpg");
    18     Mat img2=imread("2.jpg");
    19     imgs.push_back(img1);
    20     imgs.push_back(img2);
    21     Mat pano;
    22     Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    23     Stitcher::Status status = stitcher.stitch(imgs, pano);
    24     if (status != Stitcher::OK)
    25     {
    26         cout << "Can't stitch images, error code = " << status << endl;
    27         return -1;
    28     }
    29     namedWindow(result_name);
    30     imshow(result_name,pano);
    31     imwrite(result_name,pano);
    32     waitKey();
    33     return 0;
    34 }
       

    下面看一下原图和效果图,(以四张原图为例,分为左上,右上,左下,右下)

    效果图如下:

        

      可以发现代码中最关键的两句就是:

    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    Stitcher::Status status = stitcher.stitch(imgs, pano);
       

      Stitcher是OpenCV的一个类,下面看一下这个类的源代码:

    class CV_EXPORTS Stitcher
    {
    public:
        enum { ORIG_RESOL = -1 };
        enum Status { OK, ERR_NEED_MORE_IMGS };
     
        // Creates stitcher with default parameters
        static Stitcher createDefault(bool try_use_gpu = false);
     
        Status estimateTransform(InputArray images);
        Status estimateTransform(InputArray images, const std::vector<std::vector<Rect> > &rois);
     
        Status composePanorama(OutputArray pano);
        Status composePanorama(InputArray images, OutputArray pano);
     
        Status stitch(InputArray images, OutputArray pano);
        Status stitch(InputArray images, const std::vector<std::vector<Rect> > &rois, OutputArray pano);
     
        double registrationResol() const { return registr_resol_; }
        void setRegistrationResol(double resol_mpx) { registr_resol_ = resol_mpx; }
     
        double seamEstimationResol() const { return seam_est_resol_; }
        void setSeamEstimationResol(double resol_mpx) { seam_est_resol_ = resol_mpx; }
     
        double compositingResol() const { return compose_resol_; }
        void setCompositingResol(double resol_mpx) { compose_resol_ = resol_mpx; }
     
        double panoConfidenceThresh() const { return conf_thresh_; }
        void setPanoConfidenceThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
     
        bool waveCorrection() const { return do_wave_correct_; }
        void setWaveCorrection(bool flag) { do_wave_correct_ = flag; }
     
        detail::WaveCorrectKind waveCorrectKind() const { return wave_correct_kind_; }
        void setWaveCorrectKind(detail::WaveCorrectKind kind) { wave_correct_kind_ = kind; }
     
        Ptr<detail::FeaturesFinder> featuresFinder() { return features_finder_; }
        const Ptr<detail::FeaturesFinder> featuresFinder() const { return features_finder_; }
        void setFeaturesFinder(Ptr<detail::FeaturesFinder> features_finder)
            { features_finder_ = features_finder; }
     
        Ptr<detail::FeaturesMatcher> featuresMatcher() { return features_matcher_; }
        const Ptr<detail::FeaturesMatcher> featuresMatcher() const { return features_matcher_; }
        void setFeaturesMatcher(Ptr<detail::FeaturesMatcher> features_matcher)
            { features_matcher_ = features_matcher; }
     
        const cv::Mat& matchingMask() const { return matching_mask_; }
        void setMatchingMask(const cv::Mat &mask)
        {
            CV_Assert(mask.type() == CV_8U && mask.cols == mask.rows);
            matching_mask_ = mask.clone();
        }
     
        Ptr<detail::BundleAdjusterBase> bundleAdjuster() { return bundle_adjuster_; }
        const Ptr<detail::BundleAdjusterBase> bundleAdjuster() const { return bundle_adjuster_; }
        void setBundleAdjuster(Ptr<detail::BundleAdjusterBase> bundle_adjuster)
            { bundle_adjuster_ = bundle_adjuster; }
     
        Ptr<WarperCreator> warper() { return warper_; }
        const Ptr<WarperCreator> warper() const { return warper_; }
        void setWarper(Ptr<WarperCreator> warper) { warper_ = warper; }
     
        Ptr<detail::ExposureCompensator> exposureCompensator() { return exposure_comp_; }
        const Ptr<detail::ExposureCompensator> exposureCompensator() const { return exposure_comp_; }
        void setExposureCompensator(Ptr<detail::ExposureCompensator> exposure_comp)
            { exposure_comp_ = exposure_comp; }
     
        Ptr<detail::SeamFinder> seamFinder() { return seam_finder_; }
        const Ptr<detail::SeamFinder> seamFinder() const { return seam_finder_; }
        void setSeamFinder(Ptr<detail::SeamFinder> seam_finder) { seam_finder_ = seam_finder; }
     
        Ptr<detail::Blender> blender() { return blender_; }
        const Ptr<detail::Blender> blender() const { return blender_; }
        void setBlender(Ptr<detail::Blender> blender) { blender_ = blender; }
     
    private:
        /* hidden */
    };
       

      

      可以看到Stitcher大致有这些成员函数:createDefault,estimateTransform,composePanorama,stitch等等。

    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);这句话表示使用默认参数创建Stitcher类的对象stitcher,try_use_gpu表示是否打开GPU,默认不打开,即try_use_gpu=false;下面是这个函数的原型:
    
     
    C++: Stitcher Stitcher::createDefault(bool try_use_gpu=false)
    参数:Flag indicating whether GPU should be used whenever it’s possible.
    return:Stitcher class instance.(即创建了一个对象)
     
    Stitcher::Status status = stitcher.stitch(imgs, pano);这句话表示:try to stitch the given images
     
    C++: Status Stitcher::stitch(InputArray images, OutputArray pano)
    C++: Status Stitcher::stitch(InputArray images, const std::vector<std::vector<Rect>>& rois, OutputArray pano)
    参数:images – Input images.
        rois – Region of interest rectangles.(感兴趣区)
          pano – Final pano.
    return:Status code.(数据成员中枚举数组的一项)
    

     
       
       
       

      Stitcher::estimateTransform和Stitcher::composePanorama的使用为高级使用,需要清楚Stitching pipeline的过程。

    下面贴出pipeline:

    可以看出这个过程很复杂,需要涉及到很多的算法,比如:特征点的提取、特征点匹配、图像融合等等。这些过程OpenCV都为我们封装在Stitcher类中,不在此细述。

    总结

    虽然用OpenCV中的Stitcher类实现了基本的拼接,但是有一个最大的问题是,运行的效率是极低的,就这个代码中,拼接3张图片差不多用了一分钟,这在需要做实时拼接的时候是根本不可能使用的,所以后面需要做的工作任然是弄清楚Stitching pipeline的详细过程,进一步优化代码,提高拼接运行效率。

    下面贴出参考资料:

    http://docs.opencv.org/2.4.2/modules/stitching/doc/high_level.html

    下面贴出源代码和OpenCV中的stiching.cpp和stitching_detailed.cpp的下载地址:

    http://download.csdn.net/detail/u013637931/8255767

    转自:http://www.cnblogs.com/CHLL55/p/4161551.html

  • 相关阅读:
    poj 1733 Parity game
    poj 1456 Supermarket
    bzoj 1304 [CQOI 2009] 叶子的染色
    51Nod 1667 概率好题
    2015年阿里巴巴校招研发工程师在线笔试题汇总
    从字符串常量起说内存分配
    字符串笔面试题
    排序算法(4)-线性时间排序
    华为2015校园招聘机试
    笔画宽度变化(C++和matlab算法)
  • 原文地址:https://www.cnblogs.com/wyuzl/p/7676691.html
Copyright © 2011-2022 走看看