added handling of camera parameters estimation errors (#3122)
This commit is contained in:
parent
70deda354a
commit
37ea872204
modules/stitching
include/opencv2
src
samples/cpp
@ -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> ¢ers);
|
||||
void CV_EXPORTS findMaxSpanningTree(
|
||||
int num_images, const std::vector<MatchesInfo> &pairwise_matches,
|
||||
Graph &span_tree, std::vector<int> ¢ers);
|
||||
|
||||
} // namespace detail
|
||||
} // namespace cv
|
||||
|
@ -101,8 +101,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 +166,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,7 +248,21 @@ 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);
|
||||
|
||||
obtainRefinedCameraParams(cameras);
|
||||
// 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)) ||
|
||||
isinf(cam_params_.at<double>(i,0)))
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
obtainRefinedCameraParams(cameras);
|
||||
|
||||
// Normalize motion to center image
|
||||
Graph span_tree;
|
||||
@ -256,6 +273,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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user