mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 03:30:34 +08:00
added block-based gain compensator (opencv_stitching), added --preview flag.
This commit is contained in:
parent
dc3fe6e9cf
commit
7881134cf7
@ -52,8 +52,10 @@ Ptr<ExposureCompensator> ExposureCompensator::createDefault(int type)
|
|||||||
{
|
{
|
||||||
if (type == NO)
|
if (type == NO)
|
||||||
return new NoExposureCompensator();
|
return new NoExposureCompensator();
|
||||||
if (type == OVERLAP)
|
if (type == GAIN)
|
||||||
return new OverlapExposureCompensator();
|
return new GainCompensator();
|
||||||
|
if (type == GAIN_BLOCKS)
|
||||||
|
return new BlocksGainCompensator();
|
||||||
CV_Error(CV_StsBadArg, "unsupported exposure compensation method");
|
CV_Error(CV_StsBadArg, "unsupported exposure compensation method");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -69,8 +71,8 @@ void ExposureCompensator::feed(const vector<Point> &corners, const vector<Mat> &
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OverlapExposureCompensator::feed(const vector<Point> &corners, const vector<Mat> &images,
|
void GainCompensator::feed(const vector<Point> &corners, const vector<Mat> &images,
|
||||||
const vector<pair<Mat,uchar> > &masks)
|
const vector<pair<Mat,uchar> > &masks)
|
||||||
{
|
{
|
||||||
CV_Assert(corners.size() == images.size() && images.size() == masks.size());
|
CV_Assert(corners.size() == images.size() && images.size() == masks.size());
|
||||||
|
|
||||||
@ -96,7 +98,7 @@ void OverlapExposureCompensator::feed(const vector<Point> &corners, const vector
|
|||||||
submask2 = masks[j].first(Rect(roi.tl() - corners[j], roi.br() - corners[j]));
|
submask2 = masks[j].first(Rect(roi.tl() - corners[j], roi.br() - corners[j]));
|
||||||
intersect = (submask1 == masks[i].second) & (submask2 == masks[j].second);
|
intersect = (submask1 == masks[i].second) & (submask2 == masks[j].second);
|
||||||
|
|
||||||
N(i, j) = N(j, i) = countNonZero(intersect);
|
N(i, j) = N(j, i) = max(1, countNonZero(intersect));
|
||||||
|
|
||||||
double Isum1 = 0, Isum2 = 0;
|
double Isum1 = 0, Isum2 = 0;
|
||||||
for (int y = 0; y < roi.height; ++y)
|
for (int y = 0; y < roi.height; ++y)
|
||||||
@ -112,8 +114,8 @@ void OverlapExposureCompensator::feed(const vector<Point> &corners, const vector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
I(i, j) = Isum1 / max(N(i, j), 1);
|
I(i, j) = Isum1 / N(i, j);
|
||||||
I(j, i) = Isum2 / max(N(i, j), 1);
|
I(j, i) = Isum2 / N(i, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,11 +137,103 @@ void OverlapExposureCompensator::feed(const vector<Point> &corners, const vector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
solve(A, b, gains);
|
solve(A, b, gains_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OverlapExposureCompensator::apply(int index, Point /*corner*/, Mat &image, const Mat &/*mask*/)
|
void GainCompensator::apply(int index, Point /*corner*/, Mat &image, const Mat &/*mask*/)
|
||||||
{
|
{
|
||||||
image *= gains(index, 0);
|
image *= gains_(index, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vector<double> GainCompensator::gains() const
|
||||||
|
{
|
||||||
|
vector<double> gains_vec(gains_.rows);
|
||||||
|
for (int i = 0; i < gains_.rows; ++i)
|
||||||
|
gains_vec[i] = gains_(i, 0);
|
||||||
|
return gains_vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BlocksGainCompensator::feed(const vector<Point> &corners, const vector<Mat> &images,
|
||||||
|
const vector<pair<Mat,uchar> > &masks)
|
||||||
|
{
|
||||||
|
CV_Assert(corners.size() == images.size() && images.size() == masks.size());
|
||||||
|
|
||||||
|
const int num_images = static_cast<int>(images.size());
|
||||||
|
|
||||||
|
vector<Size> bl_per_imgs(num_images);
|
||||||
|
vector<Point> block_corners;
|
||||||
|
vector<Mat> block_images;
|
||||||
|
vector<pair<Mat,uchar> > block_masks;
|
||||||
|
|
||||||
|
// Construct blocks for gain compensator
|
||||||
|
for (int img_idx = 0; img_idx < num_images; ++img_idx)
|
||||||
|
{
|
||||||
|
Size bl_per_img((images[img_idx].cols + bl_width_ - 1) / bl_width_,
|
||||||
|
(images[img_idx].rows + bl_height_ - 1) / bl_height_);
|
||||||
|
int bl_width = (images[img_idx].cols + bl_per_img.width - 1) / bl_per_img.width;
|
||||||
|
int bl_height = (images[img_idx].rows + bl_per_img.height - 1) / bl_per_img.height;
|
||||||
|
bl_per_imgs[img_idx] = bl_per_img;
|
||||||
|
for (int by = 0; by < bl_per_img.height; ++by)
|
||||||
|
{
|
||||||
|
for (int bx = 0; bx < bl_per_img.width; ++bx)
|
||||||
|
{
|
||||||
|
Point bl_tl(bx * bl_width, by * bl_height);
|
||||||
|
Point bl_br(min(bl_tl.x + bl_width, images[img_idx].cols),
|
||||||
|
min(bl_tl.y + bl_height, images[img_idx].rows));
|
||||||
|
|
||||||
|
block_corners.push_back(corners[img_idx] + bl_tl);
|
||||||
|
block_images.push_back(images[img_idx](Rect(bl_tl, bl_br)));
|
||||||
|
block_masks.push_back(make_pair(masks[img_idx].first(Rect(bl_tl, bl_br)),
|
||||||
|
masks[img_idx].second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GainCompensator compensator;
|
||||||
|
compensator.feed(block_corners, block_images, block_masks);
|
||||||
|
vector<double> gains = compensator.gains();
|
||||||
|
gain_maps_.resize(num_images);
|
||||||
|
|
||||||
|
int bl_idx = 0;
|
||||||
|
for (int img_idx = 0; img_idx < num_images; ++img_idx)
|
||||||
|
{
|
||||||
|
Size bl_per_img = bl_per_imgs[img_idx];
|
||||||
|
gain_maps_[img_idx].create(bl_per_img);
|
||||||
|
|
||||||
|
for (int by = 0; by < bl_per_img.height; ++by)
|
||||||
|
for (int bx = 0; bx < bl_per_img.width; ++bx, ++bl_idx)
|
||||||
|
gain_maps_[img_idx](by, bx) = static_cast<float>(gains[bl_idx]);
|
||||||
|
|
||||||
|
Mat_<float> ker(1, 3);
|
||||||
|
ker(0,0) = 0.25; ker(0,1) = 0.5; ker(0,2) = 0.25;
|
||||||
|
sepFilter2D(gain_maps_[img_idx], gain_maps_[img_idx], CV_32F, ker, ker);
|
||||||
|
sepFilter2D(gain_maps_[img_idx], gain_maps_[img_idx], CV_32F, ker, ker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BlocksGainCompensator::apply(int index, Point /*corner*/, Mat &image, const Mat &/*mask*/)
|
||||||
|
{
|
||||||
|
CV_Assert(image.type() == CV_8UC3);
|
||||||
|
|
||||||
|
Mat_<float> gain_map;
|
||||||
|
if (gain_maps_[index].size() == image.size())
|
||||||
|
gain_map = gain_maps_[index];
|
||||||
|
else
|
||||||
|
resize(gain_maps_[index], gain_map, image.size(), 0, 0, INTER_LINEAR);
|
||||||
|
|
||||||
|
for (int y = 0; y < image.rows; ++y)
|
||||||
|
{
|
||||||
|
const float* gain_row = gain_map.ptr<float>(y);
|
||||||
|
Point3_<uchar>* row = image.ptr<Point3_<uchar> >(y);
|
||||||
|
for (int x = 0; x < image.cols; ++x)
|
||||||
|
{
|
||||||
|
row[x].x = saturate_cast<uchar>(row[x].x * gain_row[x]);
|
||||||
|
row[x].y = saturate_cast<uchar>(row[x].y * gain_row[x]);
|
||||||
|
row[x].z = saturate_cast<uchar>(row[x].z * gain_row[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -48,7 +48,7 @@
|
|||||||
class ExposureCompensator
|
class ExposureCompensator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum { NO, OVERLAP, SEGMENT };
|
enum { NO, GAIN, GAIN_BLOCKS };
|
||||||
static cv::Ptr<ExposureCompensator> createDefault(int type);
|
static cv::Ptr<ExposureCompensator> createDefault(int type);
|
||||||
|
|
||||||
void feed(const std::vector<cv::Point> &corners, const std::vector<cv::Mat> &images,
|
void feed(const std::vector<cv::Point> &corners, const std::vector<cv::Mat> &images,
|
||||||
@ -68,14 +68,31 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class OverlapExposureCompensator : public ExposureCompensator
|
class GainCompensator : public ExposureCompensator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void feed(const std::vector<cv::Point> &corners, const std::vector<cv::Mat> &images,
|
void feed(const std::vector<cv::Point> &corners, const std::vector<cv::Mat> &images,
|
||||||
const std::vector<std::pair<cv::Mat,uchar> > &masks);
|
const std::vector<std::pair<cv::Mat,uchar> > &masks);
|
||||||
void apply(int index, cv::Point corner, cv::Mat &image, const cv::Mat &mask);
|
void apply(int index, cv::Point corner, cv::Mat &image, const cv::Mat &mask);
|
||||||
|
std::vector<double> gains() const;
|
||||||
|
|
||||||
cv::Mat_<double> gains;
|
private:
|
||||||
|
cv::Mat_<double> gains_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BlocksGainCompensator : public ExposureCompensator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BlocksGainCompensator(int bl_width = 32, int bl_height = 32)
|
||||||
|
: bl_width_(bl_width), bl_height_(bl_height) {}
|
||||||
|
void feed(const std::vector<cv::Point> &corners, const std::vector<cv::Mat> &images,
|
||||||
|
const std::vector<std::pair<cv::Mat,uchar> > &masks);
|
||||||
|
void apply(int index, cv::Point corner, cv::Mat &image, const cv::Mat &mask);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int bl_width_, bl_height_;
|
||||||
|
std::vector<cv::Mat_<float> > gain_maps_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __OPENCV_EXPOSURE_COMPENSATE_HPP__
|
#endif // __OPENCV_EXPOSURE_COMPENSATE_HPP__
|
@ -41,10 +41,12 @@
|
|||||||
//M*/
|
//M*/
|
||||||
|
|
||||||
// We follow to methods described in these two papers:
|
// We follow to methods described in these two papers:
|
||||||
// - Heung-Yeung Shum and Richard Szeliski.
|
// 1) Construction of panoramic mosaics with global and local alignment.
|
||||||
// Construction of panoramic mosaics with global and local alignment. 2000.
|
// Heung-Yeung Shum and Richard Szeliski. 2000.
|
||||||
// - Matthew Brown and David G. Lowe.
|
// 2) Eliminating Ghosting and Exposure Artifacts in Image Mosaics.
|
||||||
// Automatic Panoramic Image Stitching using Invariant Features. 2007.
|
// 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 "precomp.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
@ -59,45 +61,63 @@ using namespace cv;
|
|||||||
|
|
||||||
void printUsage()
|
void printUsage()
|
||||||
{
|
{
|
||||||
cout << "Rotation model images stitcher.\n\n";
|
cout <<
|
||||||
cout << "Usage: opencv_stitching img1 img2 [...imgN]\n"
|
"Rotation model images stitcher.\n\n"
|
||||||
<< "\t[--trygpu (yes|no)]\n"
|
"opencv_stitching img1 img2 [...imgN] [flags]\n\n"
|
||||||
<< "\t[--work_megapix <float>]\n"
|
"Flags:\n"
|
||||||
<< "\t[--seam_megapix <float>]\n"
|
" --preview\n"
|
||||||
<< "\t[--compose_megapix <float>]\n"
|
" Run stitching in the preview mode. Works faster than usual mode,\n"
|
||||||
<< "\t[--match_conf <float>]\n"
|
" but output image will have lower resolution.\n"
|
||||||
<< "\t[--ba (ray|focal_ray)]\n"
|
" --try_gpu (yes|no)\n"
|
||||||
<< "\t[--conf_thresh <float>]\n"
|
" Try to use GPU. The default value is 'no'. All default values\n"
|
||||||
<< "\t[--wavecorrect (no|yes)]\n"
|
" are for CPU mode.\n"
|
||||||
<< "\t[--warp (plane|cylindrical|spherical)]\n"
|
" --work_megapix <float>\n"
|
||||||
<< "\t[--exposcomp (no|overlap)]\n"
|
" Resolution for image registration step. The default is 0.6.\n"
|
||||||
<< "\t[--seam (no|voronoi|gc_color|gc_colorgrad)]\n"
|
" --seam_megapix <float>\n"
|
||||||
<< "\t[--blend (no|feather|multiband)]\n"
|
" Resolution for seam estimation step. The default is 0.1.\n"
|
||||||
<< "\t[--numbands <int>]\n"
|
" --compose_megapix <float>\n"
|
||||||
<< "\t[--output <result_img>]\n\n";
|
" Resolution for compositing step. Use -1 for original resolution.\n"
|
||||||
cout << "--match_conf\n"
|
" The default is -1.\n"
|
||||||
<< "\tGood values are in [0.2, 0.8] range usually.\n\n";
|
" --match_conf <float>\n"
|
||||||
cout << "HINT:\n"
|
" Confidence for feature matching step. The default is 0.6.\n"
|
||||||
<< "\tTry bigger values for --work_megapix if something is wrong.\n\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
|
// Default command line args
|
||||||
vector<string> img_names;
|
vector<string> img_names;
|
||||||
bool trygpu = false;
|
bool preview = false;
|
||||||
|
bool try_gpu = false;
|
||||||
double work_megapix = 0.6;
|
double work_megapix = 0.6;
|
||||||
double seam_megapix = 0.1;
|
double seam_megapix = 0.1;
|
||||||
double compose_megapix = 1;
|
double compose_megapix = -1;
|
||||||
int ba_space = BundleAdjuster::FOCAL_RAY_SPACE;
|
int ba_space = BundleAdjuster::FOCAL_RAY_SPACE;
|
||||||
float conf_thresh = 1.f;
|
float conf_thresh = 1.f;
|
||||||
bool wave_correct = true;
|
bool wave_correct = true;
|
||||||
int warp_type = Warper::SPHERICAL;
|
int warp_type = Warper::SPHERICAL;
|
||||||
int expos_comp_type = ExposureCompensator::OVERLAP;
|
int expos_comp_type = ExposureCompensator::GAIN;
|
||||||
bool user_match_conf = false;
|
bool user_match_conf = false;
|
||||||
float match_conf = 0.6f;
|
float match_conf = 0.6f;
|
||||||
int seam_find_type = SeamFinder::GC_COLOR;
|
int seam_find_type = SeamFinder::GC_COLOR;
|
||||||
int blend_type = Blender::MULTI_BAND;
|
int blend_type = Blender::MULTI_BAND;
|
||||||
int numbands = 5;
|
int num_bands = 5;
|
||||||
string result_name = "result.png";
|
string result_name = "result.png";
|
||||||
|
|
||||||
int parseCmdArgs(int argc, char** argv)
|
int parseCmdArgs(int argc, char** argv)
|
||||||
@ -107,18 +127,21 @@ int parseCmdArgs(int argc, char** argv)
|
|||||||
printUsage();
|
printUsage();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i)
|
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")
|
if (string(argv[i + 1]) == "no")
|
||||||
trygpu = false;
|
try_gpu = false;
|
||||||
else if (string(argv[i + 1]) == "yes")
|
else if (string(argv[i + 1]) == "yes")
|
||||||
trygpu = true;
|
try_gpu = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Bad --trygpu flag value\n";
|
cout << "Bad --try_gpu flag value\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@ -167,7 +190,7 @@ int parseCmdArgs(int argc, char** argv)
|
|||||||
conf_thresh = static_cast<float>(atof(argv[i + 1]));
|
conf_thresh = static_cast<float>(atof(argv[i + 1]));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if (string(argv[i]) == "--wavecorrect")
|
else if (string(argv[i]) == "--wave_correct")
|
||||||
{
|
{
|
||||||
if (string(argv[i + 1]) == "no")
|
if (string(argv[i + 1]) == "no")
|
||||||
wave_correct = false;
|
wave_correct = false;
|
||||||
@ -175,7 +198,7 @@ int parseCmdArgs(int argc, char** argv)
|
|||||||
wave_correct = true;
|
wave_correct = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Bad --wavecorrect flag value\n";
|
cout << "Bad --wave_correct flag value\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@ -195,12 +218,14 @@ int parseCmdArgs(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if (string(argv[i]) == "--exposcomp")
|
else if (string(argv[i]) == "--expos_comp")
|
||||||
{
|
{
|
||||||
if (string(argv[i + 1]) == "no")
|
if (string(argv[i + 1]) == "no")
|
||||||
expos_comp_type = ExposureCompensator::NO;
|
expos_comp_type = ExposureCompensator::NO;
|
||||||
else if (string(argv[i + 1]) == "overlap")
|
else if (string(argv[i + 1]) == "gain")
|
||||||
expos_comp_type = ExposureCompensator::OVERLAP;
|
expos_comp_type = ExposureCompensator::GAIN;
|
||||||
|
else if (string(argv[i + 1]) == "gain_blocks")
|
||||||
|
expos_comp_type = ExposureCompensator::GAIN_BLOCKS;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Bad exposure compensation method\n";
|
cout << "Bad exposure compensation method\n";
|
||||||
@ -240,9 +265,9 @@ int parseCmdArgs(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
i++;
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
else if (string(argv[i]) == "--output")
|
else if (string(argv[i]) == "--output")
|
||||||
@ -253,6 +278,10 @@ int parseCmdArgs(int argc, char** argv)
|
|||||||
else
|
else
|
||||||
img_names.push_back(argv[i]);
|
img_names.push_back(argv[i]);
|
||||||
}
|
}
|
||||||
|
if (preview)
|
||||||
|
{
|
||||||
|
compose_megapix = work_megapix;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +310,7 @@ int main(int argc, char* argv[])
|
|||||||
int64 t = getTickCount();
|
int64 t = getTickCount();
|
||||||
|
|
||||||
vector<ImageFeatures> features(num_images);
|
vector<ImageFeatures> features(num_images);
|
||||||
SurfFeaturesFinder finder(trygpu);
|
SurfFeaturesFinder finder(try_gpu);
|
||||||
Mat full_img, img;
|
Mat full_img, img;
|
||||||
|
|
||||||
vector<Mat> images(num_images);
|
vector<Mat> images(num_images);
|
||||||
@ -333,9 +362,9 @@ int main(int argc, char* argv[])
|
|||||||
LOGLN("Pairwise matching... ");
|
LOGLN("Pairwise matching... ");
|
||||||
t = getTickCount();
|
t = getTickCount();
|
||||||
vector<MatchesInfo> pairwise_matches;
|
vector<MatchesInfo> pairwise_matches;
|
||||||
BestOf2NearestMatcher matcher(trygpu);
|
BestOf2NearestMatcher matcher(try_gpu);
|
||||||
if (user_match_conf)
|
if (user_match_conf)
|
||||||
matcher = BestOf2NearestMatcher(trygpu, match_conf);
|
matcher = BestOf2NearestMatcher(try_gpu, match_conf);
|
||||||
matcher(features, pairwise_matches);
|
matcher(features, pairwise_matches);
|
||||||
LOGLN("Pairwise matching, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
|
LOGLN("Pairwise matching, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
|
||||||
|
|
||||||
@ -533,7 +562,7 @@ int main(int argc, char* argv[])
|
|||||||
if (blend_type == Blender::MULTI_BAND)
|
if (blend_type == Blender::MULTI_BAND)
|
||||||
{
|
{
|
||||||
MultiBandBlender* mb = dynamic_cast<MultiBandBlender*>(static_cast<Blender*>(blender));
|
MultiBandBlender* mb = dynamic_cast<MultiBandBlender*>(static_cast<Blender*>(blender));
|
||||||
mb->setNumBands(numbands);
|
mb->setNumBands(num_bands);
|
||||||
}
|
}
|
||||||
blender->prepare(corners, sizes);
|
blender->prepare(corners, sizes);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user