用opencv开源包实现了下图像拼接

网上搜的都是一行代码Stitcher::Status status = stitcher.stitch(imgs, pano);就出来的傻瓜拼接,连opencv基本的包都没用。

自己好歹用了下基本的包实现了下。

鲁棒性不太好,图片少的时候没事,图片一多就出现了内存错误和木有特征点的错误。

#include <iostream>
#include <fstream>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/stitching/stitcher.hpp"
#include "opencv2/stitching/warpers.hpp"

#define MaxPics 30
//F:\Program Files\opencv\modules\stitching\include\opencv2\stitching
using namespace std;
using namespace cv;
bool try_use_gpu = false;
int filenum;
vector<Mat> imgs;
string result_name = "result.jpg";
//void printUsage();
//int parseCmdArgs(int argc, char** argv);
int readDir(char *path,char fnames[MaxPics][100]);

int readDir(char *path,char fnames[MaxPics][100])
{
 struct _finddata_t c_file;
 intptr_t hFile;
 filenum=0;

 char fullpath[100];

 sprintf(fullpath,"%s\\*.jpg",path);
 // Find first .c file in current directory
 if( (hFile = _findfirst( fullpath, &c_file )) == -1L )
  printf( "No *.jpg files in current directory %s!\n",fullpath);
 else
 {
  printf( "Listing of .jpg files in %s directory\n\n",path);
  printf( "RDO HID SYS ARC  FILE                  SIZE\n", ' ' );
  printf( "--- --- --- ---  ----                  ----\n", ' ' );
  do {
   printf( ( c_file.attrib & _A_RDONLY ) ? " Y  " : " N  " );
   printf( ( c_file.attrib & _A_SYSTEM ) ? " Y  " : " N  " );
   printf( ( c_file.attrib & _A_HIDDEN ) ? " Y  " : " N  " );
   printf( ( c_file.attrib & _A_ARCH )   ? " Y  " : " N  " );
   //ctime_s( buffer, _countof(buffer), &c_file.time_write );
   printf( " %-15s  %9ld\n",c_file.name, c_file.size );
   sprintf(fnames[filenum],"%s\\%s",path,c_file.name);
   filenum++;
  } while( _findnext( hFile, &c_file ) == 0 );
  _findclose( hFile );
 }
 return filenum;
}
int main(int argc, char* argv[])
{
 clock_t start,finish;
   double totaltime;
   start=clock();

  
 argv[1]="pic";
 char fdir[MaxPics][100];
 filenum = readDir(argv[1],fdir);
 Mat img, pano;
 for(int i=0 ; i<filenum ;i++){
  img = imread(fdir[i]);
  imgs.push_back(img);
 }
 Stitcher stitcher =  Stitcher::createDefault(try_use_gpu);
 stitcher.setRegistrationResol(0.1);//为了加速,我选0.1,默认是0.6,最大值1最慢,此方法用于特征点检测阶段,如果找不到特征点,调高吧
    //stitcher.setSeamEstimationResol(0.1);//默认是0.1
    //stitcher.setCompositingResol(-1);//默认是-1,用于特征点检测阶段,找不到特征点的话,改-1
 stitcher.setPanoConfidenceThresh(1);//默认是1,见过有设0.6和0.4的
    stitcher.setWaveCorrection(false);//默认是true,为加速选false,表示跳过WaveCorrection步骤
    //stitcher.setWaveCorrectKind(detail::WAVE_CORRECT_HORIZ);//还可以选detail::WAVE_CORRECT_VERT ,波段修正(wave correction)功能(水平方向/垂直方向修正)。因为setWaveCorrection设的false,此语句没用
 
 //找特征点surf算法,此算法计算量大,但对刚体运动、缩放、环境影响等情况下较为稳定
 detail::SurfFeaturesFinder *featureFinder = new detail::SurfFeaturesFinder();
 stitcher.setFeaturesFinder(featureFinder);
 
 //找特征点ORB算法,但是发现草地这组图,这个算法不能完成拼接
 //detail::OrbFeaturesFinder *featureFinder = new detail::OrbFeaturesFinder();
 //stitcher.setFeaturesFinder(featureFinder);

    //Features matcher which finds two best matches for each feature and leaves the best one only if the ratio between descriptor distances is greater than the threshold match_conf.
 detail::BestOf2NearestMatcher *matcher = new detail::BestOf2NearestMatcher(false, 0.5f/*=match_conf默认是0.65,我选0.8,选太大了就没特征点啦,0.8都失败了*/);
 stitcher.setFeaturesMatcher(matcher);
   
 // Rotation Estimation,It takes features of all images, pairwise matches between all images and estimates rotations of all cameras.
 //Implementation of the camera parameters refinement algorithm which minimizes sum of the distances between the rays passing through the camera center and a feature,这个耗时短
 stitcher.setBundleAdjuster(new detail::BundleAdjusterRay());
 //Implementation of the camera parameters refinement algorithm which minimizes sum of the reprojection error squares.
 //stitcher.setBundleAdjuster(new detail::BundleAdjusterReproj());
 
 //Seam Estimation
 //Minimum graph cut-based seam estimator
  //stitcher.setSeamFinder(new detail::GraphCutSeamFinder(detail::GraphCutSeamFinderBase::COST_COLOR));//默认就是这个
 //stitcher.setSeamFinder(new detail::GraphCutSeamFinder(detail::GraphCutSeamFinderBase::COST_COLOR_GRAD));//GraphCutSeamFinder的第二种形式
 //啥SeamFinder也不用,Stub seam estimator which does nothing.
 stitcher.setSeamFinder(new detail::NoSeamFinder);
 //Voronoi diagram-based seam estimator.
 //stitcher.setSeamFinder(new detail::VoronoiSeamFinder);

 //exposure compensators曝光补偿
 //stitcher.setExposureCompensator(new detail::BlocksGainCompensator());//默认的就是这个
 //不要曝光补偿
 stitcher.setExposureCompensator(new detail::NoExposureCompensator());
 //Exposure compensator which tries to remove exposure related artifacts by adjusting image intensities
 //stitcher.setExposureCompensator(new detail::detail::GainCompensator());
 //Exposure compensator which tries to remove exposure related artifacts by adjusting image block intensities 
 //stitcher.setExposureCompensator(new detail::detail::BlocksGainCompensator());
 
 //Image Blenders
 //Blender which uses multi-band blending algorithm
 //stitcher.setBlender(new detail::MultiBandBlender(try_use_gpu));//默认的是这个
 //Simple blender which mixes images at its borders
 stitcher.setBlender(new detail::FeatherBlender());//这个简单,耗时少

 //柱面?球面OR平面?默认为球面
 PlaneWarper*  cw = new PlaneWarper();
 //SphericalWarper*  cw = new SphericalWarper();
 //CylindricalWarper*  cw = new CylindricalWarper();
 stitcher.setWarper(cw);

 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;
 }
 cout<<"程序开始";
 imwrite(result_name, pano);
 finish=clock();
   totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
   cout<<"\n此程序的运行时间为"<<totaltime<<"秒!"<<endl;
 return 0;
}

至于其他的拼接方式,http://academy.nearsoft.com/project-updates/makingapanoramapicture写的挺好。我引用之,并总结如下

1,Stitcher class from OpenCV library

 

  • Pros
    • Extremely simple. Build panorama in just one command.
    • It performs from finding features through blending in the selected projection by itself.
  • Cons
    • Uses SURF algorithm (patented, not allowed for commercial use).
    • Slow at searching for features, running on a smartphone

2,BoofCV

 

  • Pros
    • Still easy to use.
    • Java native.
  • Cons
    • It blends without warping into the spherical projection.
    • Still uses SURF.

当然自己实现最好,我的上述代码就是第一种了

 

 

转载于:https://www.cnblogs.com/monoid/archive/2013/05/04/3059894.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值