版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36576377/article/details/79689070
#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;
argv[1] = "d:\\1";
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);
}
start = clock();
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;
}