added histograms comparison into opencv_stitching

This commit is contained in:
Alexey Spizhevoy 2011-05-20 07:32:25 +00:00
parent 63ac784ea0
commit 767a6e8e78
5 changed files with 65 additions and 15 deletions

View File

@ -56,7 +56,7 @@ double estimateFocal(const vector<Mat> &images, const vector<ImageFeatures> &/*f
}
}
if (focals.size() >= 2 * (num_images - 1))
if (static_cast<int>(focals.size()) >= 2 * (num_images - 1))
{
nth_element(focals.begin(), focals.end(), focals.begin() + focals.size()/2);
return focals[focals.size()/2];

View File

@ -26,6 +26,9 @@ void printUsage()
<< "\t[--output <result_img>]\n\n";
cout << "--matchconf\n"
<< "\tGood values are in [0.2, 0.8] range usually.\n\n";
cout << "HINT:\n"
<< "\tDefault parameters are for '--trygpu no' configuration.\n"
<< "\tTry bigger values for --work_megapix if something is wrong.\n\n";
}
int main(int argc, char* argv[])
@ -35,15 +38,17 @@ int main(int argc, char* argv[])
vector<string> img_names;
vector<Mat> images;
bool trygpu = true;
double work_megapix = 1;
// Default parameters
bool trygpu = false;
double work_megapix = 0.2;
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;
bool user_match_conf = false;
float match_conf = 0.55f;
float match_conf = 0.6f;
int seam_find_type = SeamFinder::VORONOI;
int blend_type = Blender::MULTI_BAND;
string result_name = "result.png";

View File

@ -1,5 +1,6 @@
#include <algorithm>
#include <functional>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/gpu/gpu.hpp>
#include "matchers.hpp"
@ -9,6 +10,31 @@ using namespace std;
using namespace cv;
using namespace cv::gpu;
//////////////////////////////////////////////////////////////////////////////
void FeaturesFinder::operator ()(const vector<Mat> &images, vector<ImageFeatures> &features)
{
features.resize(images.size());
// Calculate histograms
for (size_t i = 0; i < images.size(); ++i)
{
Mat hsv;
cvtColor(images[i], hsv, CV_BGR2HSV);
int hbins = 30, sbins = 32, vbins = 30;
int hist_size[] = { hbins, sbins, vbins };
float hranges[] = { 0, 180 };
float sranges[] = { 0, 256 };
float vranges[] = { 0, 256 };
const float* ranges[] = { hranges, sranges, vranges };
int channels[] = { 0, 1, 2 };
calcHist(&hsv, 1, channels, Mat(), features[i].hist, 3, hist_size, ranges);
}
find(images, features);
}
//////////////////////////////////////////////////////////////////////////////
namespace
@ -19,7 +45,7 @@ namespace
inline CpuSurfFeaturesFinder(double hess_thresh, int num_octaves, int num_layers,
int num_octaves_descr, int num_layers_descr)
{
detector_ = new /*FastFeatureDetector;*/SurfFeatureDetector(hess_thresh, num_octaves, num_layers);
detector_ = new SurfFeatureDetector(hess_thresh, num_octaves, num_layers);
extractor_ = new SurfDescriptorExtractor(num_octaves_descr, num_layers_descr);
}
@ -149,14 +175,32 @@ void FeaturesMatcher::operator ()(const vector<Mat> &images, const vector<ImageF
for (size_t i = 0; i < images.size(); ++i)
{
LOGLN("Processing image " << i << "... ");
for (size_t j = 0; j < images.size(); ++j)
for (size_t j = i + 1; j < images.size(); ++j)
{
if (i == j)
// Save time by ignoring poor pairs
if (compareHist(features[i].hist, features[j].hist, CV_COMP_INTERSECT)
< min(images[i].size().area(), images[j].size().area()) * 0.4)
{
//LOGLN("Ignoring (" << i << ", " << j << ") pair...");
continue;
}
size_t pair_idx = i * images.size() + j;
(*this)(images[i], features[i], images[j], features[j], pairwise_matches[pair_idx]);
pairwise_matches[pair_idx].src_img_idx = i;
pairwise_matches[pair_idx].dst_img_idx = j;
// Set up dual pair matches info
size_t dual_pair_idx = j * images.size() + i;
pairwise_matches[dual_pair_idx] = pairwise_matches[pair_idx];
pairwise_matches[dual_pair_idx].src_img_idx = j;
pairwise_matches[dual_pair_idx].dst_img_idx = i;
if (!pairwise_matches[pair_idx].H.empty())
pairwise_matches[dual_pair_idx].H = pairwise_matches[pair_idx].H.inv();
for (size_t i = 0; i < pairwise_matches[dual_pair_idx].matches.size(); ++i)
swap(pairwise_matches[dual_pair_idx].matches[i].queryIdx,
pairwise_matches[dual_pair_idx].matches[i].trainIdx);
}
}
}

View File

@ -7,6 +7,7 @@
struct ImageFeatures
{
cv::Mat hist;
std::vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;
};
@ -16,7 +17,7 @@ class FeaturesFinder
{
public:
virtual ~FeaturesFinder() {}
void operator ()(const std::vector<cv::Mat> &images, std::vector<ImageFeatures> &features) { find(images, features); }
void operator ()(const std::vector<cv::Mat> &images, std::vector<ImageFeatures> &features);
protected:
virtual void find(const std::vector<cv::Mat> &images, std::vector<ImageFeatures> &features) = 0;
@ -26,7 +27,7 @@ protected:
class SurfFeaturesFinder : public FeaturesFinder
{
public:
explicit SurfFeaturesFinder(bool try_use_gpu = true, double hess_thresh = 500.0,
SurfFeaturesFinder(bool try_use_gpu = true, double hess_thresh = 300.0,
int num_octaves = 3, int num_layers = 4,
int num_octaves_descr = 4, int num_layers_descr = 2);
@ -70,7 +71,7 @@ protected:
class BestOf2NearestMatcher : public FeaturesMatcher
{
public:
explicit BestOf2NearestMatcher(bool try_use_gpu = true, float match_conf = 0.55f, int num_matches_thresh1 = 5, int num_matches_thresh2 = 5);
BestOf2NearestMatcher(bool try_use_gpu = true, float match_conf = 0.55f, int num_matches_thresh1 = 6, int num_matches_thresh2 = 6);
protected:
void match(const cv::Mat &img1, const ImageFeatures &features1, const cv::Mat &img2, const ImageFeatures &features2,

View File

@ -130,7 +130,7 @@ void BundleAdjuster::estimate(const vector<Mat> &images, const vector<ImageFeatu
total_num_matches_ += static_cast<int>(pairwise_matches[edges_[i].first * num_images_ + edges_[i].second].num_inliers);
CvLevMarq solver(num_images_ * 4, total_num_matches_ * 3,
cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 100, DBL_EPSILON));
cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 1000, DBL_EPSILON));
CvMat matParams = cameras_;
cvCopy(&matParams, solver.param);
@ -142,7 +142,7 @@ void BundleAdjuster::estimate(const vector<Mat> &images, const vector<ImageFeatu
CvMat* _J = 0;
CvMat* _err = 0;
bool proceed = solver.update( _param, _J, _err );
bool proceed = solver.update(_param, _J, _err);
cvCopy( _param, &matParams );