Commit 4c03afe0 authored by Andrey Pavlenko's avatar Andrey Pavlenko Committed by OpenCV Buildbot

Merge pull request #1079 from AlexeySpizhevoy:master

parents 8a3aa1f5 dcb049df
......@@ -18,12 +18,11 @@ Rotation estimator base class. It takes features of all images, pairwise matches
public:
virtual ~Estimator() {}
void operator ()(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras)
{ estimate(features, pairwise_matches, cameras); }
bool operator ()(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras);
protected:
virtual void estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
virtual bool estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras) = 0;
};
......@@ -32,7 +31,7 @@ detail::Estimator::operator()
Estimates camera parameters.
.. ocv:function:: detail::Estimator::operator ()(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches, std::vector<CameraParams> &cameras)
.. ocv:function:: bool detail::Estimator::operator ()(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches, std::vector<CameraParams> &cameras)
:param features: Features of images
......@@ -40,12 +39,14 @@ Estimates camera parameters.
:param cameras: Estimated camera parameters
:return: True in case of success, false otherwise
detail::Estimator::estimate
---------------------------
This method must implement camera parameters estimation logic in order to make the wrapper `detail::Estimator::operator()`_ work.
.. ocv:function:: void detail::Estimator::estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches, std::vector<CameraParams> &cameras)
.. ocv:function:: bool detail::Estimator::estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches, std::vector<CameraParams> &cameras)
:param features: Features of images
......@@ -53,6 +54,8 @@ This method must implement camera parameters estimation logic in order to make t
:param cameras: Estimated camera parameters
:return: True in case of success, false otherwise
detail::HomographyBasedEstimator
--------------------------------
.. ocv:class:: detail::HomographyBasedEstimator : public detail::Estimator
......
......@@ -59,7 +59,13 @@ class CV_EXPORTS Stitcher
{
public:
enum { ORIG_RESOL = -1 };
enum Status { OK, ERR_NEED_MORE_IMGS };
enum Status
{
OK = 0,
ERR_NEED_MORE_IMGS = 1,
ERR_HOMOGRAPHY_EST_FAIL = 2,
ERR_CAMERA_PARAMS_ADJUST_FAIL = 3
};
// Creates stitcher with default parameters
static Stitcher createDefault(bool try_use_gpu = false);
......@@ -138,7 +144,7 @@ private:
Stitcher() {}
Status matchImages();
void estimateCameraParams();
Status estimateCameraParams();
double registr_resol_;
double seam_est_resol_;
......
......@@ -56,12 +56,14 @@ class CV_EXPORTS Estimator
public:
virtual ~Estimator() {}
void operator ()(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
bool operator ()(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras)
{ estimate(features, pairwise_matches, cameras); }
{ return estimate(features, pairwise_matches, cameras); }
protected:
virtual void estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras) = 0;
};
......@@ -73,8 +75,9 @@ public:
: is_focals_estimated_(is_focals_estimated) {}
private:
void estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras);
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras);
bool is_focals_estimated_;
};
......@@ -107,7 +110,7 @@ protected:
}
// Runs bundle adjustment
virtual void estimate(const std::vector<ImageFeatures> &features,
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras);
......@@ -193,11 +196,14 @@ void CV_EXPORTS waveCorrect(std::vector<Mat> &rmats, WaveCorrectKind kind);
String CV_EXPORTS matchesGraphAsString(std::vector<String> &pathes, std::vector<MatchesInfo> &pairwise_matches,
float conf_threshold);
std::vector<int> CV_EXPORTS leaveBiggestComponent(std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches,
float conf_threshold);
std::vector<int> CV_EXPORTS leaveBiggestComponent(
std::vector<ImageFeatures> &features,
std::vector<MatchesInfo> &pairwise_matches,
float conf_threshold);
void CV_EXPORTS findMaxSpanningTree(int num_images, const std::vector<MatchesInfo> &pairwise_matches,
Graph &span_tree, std::vector<int> &centers);
void CV_EXPORTS findMaxSpanningTree(
int num_images, const std::vector<MatchesInfo> &pairwise_matches,
Graph &span_tree, std::vector<int> &centers);
} // namespace detail
} // namespace cv
......
......@@ -43,6 +43,13 @@
#include "precomp.hpp"
#include "opencv2/calib3d/calib3d_c.h"
#ifdef _MSC_VER
#include <float.h>
#define isnan(x) _isnan(x)
#else
#include <math.h>
#endif
using namespace cv;
using namespace cv::detail;
......@@ -101,8 +108,10 @@ void calcDeriv(const Mat &err1, const Mat &err2, double h, Mat res)
namespace cv {
namespace detail {
void HomographyBasedEstimator::estimate(const std::vector<ImageFeatures> &features, const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras)
bool HomographyBasedEstimator::estimate(
const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras)
{
LOGLN("Estimating rotations...");
#if ENABLE_LOG
......@@ -164,12 +173,13 @@ void HomographyBasedEstimator::estimate(const std::vector<ImageFeatures> &featur
}
LOGLN("Estimating rotations, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
return true;
}
//////////////////////////////////////////////////////////////////////////////
void BundleAdjusterBase::estimate(const std::vector<ImageFeatures> &features,
bool BundleAdjusterBase::estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras)
{
......@@ -245,6 +255,19 @@ void BundleAdjusterBase::estimate(const std::vector<ImageFeatures> &features,
LOGLN_CHAT("Bundle adjustment, final RMS error: " << std::sqrt(err.dot(err) / total_num_matches_));
LOGLN_CHAT("Bundle adjustment, iterations done: " << iter);
// Check if all camera parameters are valid
bool ok = true;
for (int i = 0; i < cam_params_.rows; ++i)
{
if (isnan(cam_params_.at<double>(i,0)))
{
ok = false;
break;
}
}
if (!ok)
return false;
obtainRefinedCameraParams(cameras);
// Normalize motion to center image
......@@ -256,6 +279,7 @@ void BundleAdjusterBase::estimate(const std::vector<ImageFeatures> &features,
cameras[i].R = R_inv * cameras[i].R;
LOGLN_CHAT("Bundle adjustment, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
return true;
}
......
......@@ -102,7 +102,8 @@ Stitcher::Status Stitcher::estimateTransform(InputArray images, const std::vecto
if ((status = matchImages()) != OK)
return status;
estimateCameraParams();
if ((status = estimateCameraParams()) != OK)
return status;
return OK;
}
......@@ -442,10 +443,11 @@ Stitcher::Status Stitcher::matchImages()
}
void Stitcher::estimateCameraParams()
Stitcher::Status Stitcher::estimateCameraParams()
{
detail::HomographyBasedEstimator estimator;
estimator(features_, pairwise_matches_, cameras_);
if (!estimator(features_, pairwise_matches_, cameras_))
return ERR_HOMOGRAPHY_EST_FAIL;
for (size_t i = 0; i < cameras_.size(); ++i)
{
......@@ -456,7 +458,8 @@ void Stitcher::estimateCameraParams()
}
bundle_adjuster_->setConfThresh(conf_thresh_);
(*bundle_adjuster_)(features_, pairwise_matches_, cameras_);
if (!(*bundle_adjuster_)(features_, pairwise_matches_, cameras_))
return ERR_CAMERA_PARAMS_ADJUST_FAIL;
// Find median focal length and use it as final image scale
std::vector<double> focals;
......@@ -481,6 +484,8 @@ void Stitcher::estimateCameraParams()
for (size_t i = 0; i < cameras_.size(); ++i)
cameras_[i].R = rmats[i];
}
return OK;
}
} // namespace cv
......@@ -469,7 +469,11 @@ int main(int argc, char* argv[])
HomographyBasedEstimator estimator;
vector<CameraParams> cameras;
estimator(features, pairwise_matches, cameras);
if (!estimator(features, pairwise_matches, cameras))
{
cout << "Homography estimation failed.\n";
return -1;
}
for (size_t i = 0; i < cameras.size(); ++i)
{
......@@ -495,7 +499,11 @@ int main(int argc, char* argv[])
if (ba_refine_mask[3] == 'x') refine_mask(1,1) = 1;
if (ba_refine_mask[4] == 'x') refine_mask(1,2) = 1;
adjuster->setRefinementMask(refine_mask);
(*adjuster)(features, pairwise_matches, cameras);
if (!(*adjuster)(features, pairwise_matches, cameras))
{
cout << "Camera parameters adjusting failed.\n";
return -1;
}
// Find median focal length
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment