added block-based gain compensator (opencv_stitching), added --preview flag.
This commit is contained in:
@@ -41,10 +41,12 @@
|
||||
//M*/
|
||||
|
||||
// We follow to methods described in these two papers:
|
||||
// - Heung-Yeung Shum and Richard Szeliski.
|
||||
// Construction of panoramic mosaics with global and local alignment. 2000.
|
||||
// - Matthew Brown and David G. Lowe.
|
||||
// Automatic Panoramic Image Stitching using Invariant Features. 2007.
|
||||
// 1) Construction of panoramic mosaics with global and local alignment.
|
||||
// Heung-Yeung Shum and Richard Szeliski. 2000.
|
||||
// 2) Eliminating Ghosting and Exposure Artifacts in Image Mosaics.
|
||||
// Matthew Uyttendaele, Ashley Eden and Richard Szeliski. 2001.
|
||||
// 3) Automatic Panoramic Image Stitching using Invariant Features.
|
||||
// Matthew Brown and David G. Lowe. 2007.
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "util.hpp"
|
||||
@@ -59,45 +61,63 @@ using namespace cv;
|
||||
|
||||
void printUsage()
|
||||
{
|
||||
cout << "Rotation model images stitcher.\n\n";
|
||||
cout << "Usage: opencv_stitching img1 img2 [...imgN]\n"
|
||||
<< "\t[--trygpu (yes|no)]\n"
|
||||
<< "\t[--work_megapix <float>]\n"
|
||||
<< "\t[--seam_megapix <float>]\n"
|
||||
<< "\t[--compose_megapix <float>]\n"
|
||||
<< "\t[--match_conf <float>]\n"
|
||||
<< "\t[--ba (ray|focal_ray)]\n"
|
||||
<< "\t[--conf_thresh <float>]\n"
|
||||
<< "\t[--wavecorrect (no|yes)]\n"
|
||||
<< "\t[--warp (plane|cylindrical|spherical)]\n"
|
||||
<< "\t[--exposcomp (no|overlap)]\n"
|
||||
<< "\t[--seam (no|voronoi|gc_color|gc_colorgrad)]\n"
|
||||
<< "\t[--blend (no|feather|multiband)]\n"
|
||||
<< "\t[--numbands <int>]\n"
|
||||
<< "\t[--output <result_img>]\n\n";
|
||||
cout << "--match_conf\n"
|
||||
<< "\tGood values are in [0.2, 0.8] range usually.\n\n";
|
||||
cout << "HINT:\n"
|
||||
<< "\tTry bigger values for --work_megapix if something is wrong.\n\n";
|
||||
cout <<
|
||||
"Rotation model images stitcher.\n\n"
|
||||
"opencv_stitching img1 img2 [...imgN] [flags]\n\n"
|
||||
"Flags:\n"
|
||||
" --preview\n"
|
||||
" Run stitching in the preview mode. Works faster than usual mode,\n"
|
||||
" but output image will have lower resolution.\n"
|
||||
" --try_gpu (yes|no)\n"
|
||||
" Try to use GPU. The default value is 'no'. All default values\n"
|
||||
" are for CPU mode.\n"
|
||||
" --work_megapix <float>\n"
|
||||
" Resolution for image registration step. The default is 0.6.\n"
|
||||
" --seam_megapix <float>\n"
|
||||
" Resolution for seam estimation step. The default is 0.1.\n"
|
||||
" --compose_megapix <float>\n"
|
||||
" Resolution for compositing step. Use -1 for original resolution.\n"
|
||||
" The default is -1.\n"
|
||||
" --match_conf <float>\n"
|
||||
" Confidence for feature matching step. The default is 0.6.\n"
|
||||
" --ba (ray|focal_ray)\n"
|
||||
" Bundle adjustment cost function. The default is 'focal_ray'.\n"
|
||||
" --conf_thresh <float>\n"
|
||||
" Threshold for two images are from the same panorama confidence.\n"
|
||||
" The default is 'focal_ray'.\n"
|
||||
" --wave_correct (no|yes)\n"
|
||||
" Perform wave effect correction. The default is 'yes'.\n"
|
||||
" --warp (plane|cylindrical|spherical)\n"
|
||||
" Warp surface type. The default is 'spherical'.\n"
|
||||
" --expos_comp (no|gain|gain_blocks)\n"
|
||||
" Exposure compensation method. The default is 'gain'.\n"
|
||||
" --seam (no|voronoi|gc_color|gc_colorgrad)\n"
|
||||
" Seam estimation method. The default is 'gc_color'.\n"
|
||||
" --blend (no|feather|multiband)\n"
|
||||
" Blending method. The default is 'multiband'.\n"
|
||||
" --num_bands <int>\n"
|
||||
" Number of bands for multi-band blending method. The default is 5.\n"
|
||||
" --output <result_img>\n";
|
||||
}
|
||||
|
||||
|
||||
// Default command line args
|
||||
vector<string> img_names;
|
||||
bool trygpu = false;
|
||||
bool preview = false;
|
||||
bool try_gpu = false;
|
||||
double work_megapix = 0.6;
|
||||
double seam_megapix = 0.1;
|
||||
double compose_megapix = 1;
|
||||
double compose_megapix = -1;
|
||||
int ba_space = BundleAdjuster::FOCAL_RAY_SPACE;
|
||||
float conf_thresh = 1.f;
|
||||
bool wave_correct = true;
|
||||
int warp_type = Warper::SPHERICAL;
|
||||
int expos_comp_type = ExposureCompensator::OVERLAP;
|
||||
int expos_comp_type = ExposureCompensator::GAIN;
|
||||
bool user_match_conf = false;
|
||||
float match_conf = 0.6f;
|
||||
int seam_find_type = SeamFinder::GC_COLOR;
|
||||
int blend_type = Blender::MULTI_BAND;
|
||||
int numbands = 5;
|
||||
int num_bands = 5;
|
||||
string result_name = "result.png";
|
||||
|
||||
int parseCmdArgs(int argc, char** argv)
|
||||
@@ -107,18 +127,21 @@ int parseCmdArgs(int argc, char** argv)
|
||||
printUsage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (string(argv[i]) == "--trygpu")
|
||||
if (string(argv[i]) == "--preview")
|
||||
{
|
||||
preview = true;
|
||||
}
|
||||
else if (string(argv[i]) == "--try_gpu")
|
||||
{
|
||||
if (string(argv[i + 1]) == "no")
|
||||
trygpu = false;
|
||||
try_gpu = false;
|
||||
else if (string(argv[i + 1]) == "yes")
|
||||
trygpu = true;
|
||||
try_gpu = true;
|
||||
else
|
||||
{
|
||||
cout << "Bad --trygpu flag value\n";
|
||||
cout << "Bad --try_gpu flag value\n";
|
||||
return -1;
|
||||
}
|
||||
i++;
|
||||
@@ -167,7 +190,7 @@ int parseCmdArgs(int argc, char** argv)
|
||||
conf_thresh = static_cast<float>(atof(argv[i + 1]));
|
||||
i++;
|
||||
}
|
||||
else if (string(argv[i]) == "--wavecorrect")
|
||||
else if (string(argv[i]) == "--wave_correct")
|
||||
{
|
||||
if (string(argv[i + 1]) == "no")
|
||||
wave_correct = false;
|
||||
@@ -175,7 +198,7 @@ int parseCmdArgs(int argc, char** argv)
|
||||
wave_correct = true;
|
||||
else
|
||||
{
|
||||
cout << "Bad --wavecorrect flag value\n";
|
||||
cout << "Bad --wave_correct flag value\n";
|
||||
return -1;
|
||||
}
|
||||
i++;
|
||||
@@ -195,12 +218,14 @@ int parseCmdArgs(int argc, char** argv)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else if (string(argv[i]) == "--exposcomp")
|
||||
else if (string(argv[i]) == "--expos_comp")
|
||||
{
|
||||
if (string(argv[i + 1]) == "no")
|
||||
expos_comp_type = ExposureCompensator::NO;
|
||||
else if (string(argv[i + 1]) == "overlap")
|
||||
expos_comp_type = ExposureCompensator::OVERLAP;
|
||||
else if (string(argv[i + 1]) == "gain")
|
||||
expos_comp_type = ExposureCompensator::GAIN;
|
||||
else if (string(argv[i + 1]) == "gain_blocks")
|
||||
expos_comp_type = ExposureCompensator::GAIN_BLOCKS;
|
||||
else
|
||||
{
|
||||
cout << "Bad exposure compensation method\n";
|
||||
@@ -240,9 +265,9 @@ int parseCmdArgs(int argc, char** argv)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else if (string(argv[i]) == "--numbands")
|
||||
else if (string(argv[i]) == "--num_bands")
|
||||
{
|
||||
numbands = atoi(argv[i + 1]);
|
||||
num_bands = atoi(argv[i + 1]);
|
||||
i++;
|
||||
}
|
||||
else if (string(argv[i]) == "--output")
|
||||
@@ -253,6 +278,10 @@ int parseCmdArgs(int argc, char** argv)
|
||||
else
|
||||
img_names.push_back(argv[i]);
|
||||
}
|
||||
if (preview)
|
||||
{
|
||||
compose_megapix = work_megapix;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -281,7 +310,7 @@ int main(int argc, char* argv[])
|
||||
int64 t = getTickCount();
|
||||
|
||||
vector<ImageFeatures> features(num_images);
|
||||
SurfFeaturesFinder finder(trygpu);
|
||||
SurfFeaturesFinder finder(try_gpu);
|
||||
Mat full_img, img;
|
||||
|
||||
vector<Mat> images(num_images);
|
||||
@@ -333,9 +362,9 @@ int main(int argc, char* argv[])
|
||||
LOGLN("Pairwise matching... ");
|
||||
t = getTickCount();
|
||||
vector<MatchesInfo> pairwise_matches;
|
||||
BestOf2NearestMatcher matcher(trygpu);
|
||||
BestOf2NearestMatcher matcher(try_gpu);
|
||||
if (user_match_conf)
|
||||
matcher = BestOf2NearestMatcher(trygpu, match_conf);
|
||||
matcher = BestOf2NearestMatcher(try_gpu, match_conf);
|
||||
matcher(features, pairwise_matches);
|
||||
LOGLN("Pairwise matching, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
|
||||
|
||||
@@ -533,7 +562,7 @@ int main(int argc, char* argv[])
|
||||
if (blend_type == Blender::MULTI_BAND)
|
||||
{
|
||||
MultiBandBlender* mb = dynamic_cast<MultiBandBlender*>(static_cast<Blender*>(blender));
|
||||
mb->setNumBands(numbands);
|
||||
mb->setNumBands(num_bands);
|
||||
}
|
||||
blender->prepare(corners, sizes);
|
||||
}
|
||||
|
Reference in New Issue
Block a user