diff --git a/modules/stitching/blenders.hpp b/modules/stitching/blenders.hpp index af52f8a939..4595877ecc 100644 --- a/modules/stitching/blenders.hpp +++ b/modules/stitching/blenders.hpp @@ -114,7 +114,7 @@ void createLaplacePyr(const cv::Mat &img, int num_levels, std::vector& void createLaplacePyrGpu(const cv::Mat &img, int num_levels, std::vector& pyr); #endif -// Restores source image in-place (result will be stored in pyr[0]) +// Restores source image void restoreImageFromLaplacePyr(std::vector& pyr); #endif // __OPENCV_BLENDERS_HPP__ diff --git a/modules/stitching/exposure_compensate.cpp b/modules/stitching/exposure_compensate.cpp index 9bbb6c3d64..218ac5ee69 100644 --- a/modules/stitching/exposure_compensate.cpp +++ b/modules/stitching/exposure_compensate.cpp @@ -50,13 +50,13 @@ using namespace cv::gpu; Ptr ExposureCompensator::createDefault(int type) { - if (type == NO) - return new NoExposureCompensator(); - if (type == GAIN) - return new GainCompensator(); - if (type == GAIN_BLOCKS) - return new BlocksGainCompensator(); - CV_Error(CV_StsBadArg, "unsupported exposure compensation method"); + if (type == NO) + return new NoExposureCompensator(); + if (type == GAIN) + return new GainCompensator(); + if (type == GAIN_BLOCKS) + return new BlocksGainCompensator(); + CV_Error(CV_StsBadArg, "unsupported exposure compensation method"); return NULL; } @@ -74,6 +74,9 @@ void ExposureCompensator::feed(const vector &corners, const vector & void GainCompensator::feed(const vector &corners, const vector &images, const vector > &masks) { + LOGLN("Exposure compensation..."); + int64 t = getTickCount(); + CV_Assert(corners.size() == images.size() && images.size() == masks.size()); const int num_images = static_cast(images.size()); @@ -138,6 +141,8 @@ void GainCompensator::feed(const vector &corners, const vector &imag } solve(A, b, gains_); + + LOGLN("Exposure compensation, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); } @@ -237,4 +242,4 @@ void BlocksGainCompensator::apply(int index, Point /*corner*/, Mat &image, const row[x].z = saturate_cast(row[x].z * gain_row[x]); } } -} \ No newline at end of file +} diff --git a/modules/stitching/main.cpp b/modules/stitching/main.cpp index c915856387..1ebe774d3d 100644 --- a/modules/stitching/main.cpp +++ b/modules/stitching/main.cpp @@ -80,7 +80,7 @@ void printUsage() " --conf_thresh \n" " Threshold for two images are from the same panorama confidence.\n" " The default is 1.0.\n" - " --ba (ray|focal_ray)\n" + " --ba (no|ray|focal_ray)\n" " Bundle adjustment cost function. The default is 'focal_ray'.\n" " --wave_correct (no|yes)\n" " Perform wave effect correction. The default is 'yes'.\n" @@ -187,7 +187,9 @@ int parseCmdArgs(int argc, char** argv) } else if (string(argv[i]) == "--ba") { - if (string(argv[i + 1]) == "ray") + if (string(argv[i + 1]) == "no") + ba_space = BundleAdjuster::NO; + else if (string(argv[i + 1]) == "ray") ba_space = BundleAdjuster::RAY_SPACE; else if (string(argv[i + 1]) == "focal_ray") ba_space = BundleAdjuster::FOCAL_RAY_SPACE; @@ -423,12 +425,9 @@ int main(int argc, char* argv[]) return -1; } - LOGLN("Estimating rotations..."); - t = getTickCount(); HomographyBasedEstimator estimator; vector cameras; estimator(features, pairwise_matches, cameras); - LOGLN("Estimating rotations, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); for (size_t i = 0; i < cameras.size(); ++i) { @@ -438,11 +437,8 @@ int main(int argc, char* argv[]) LOGLN("Initial focal length #" << indices[i]+1 << ": " << cameras[i].focal); } - LOG("Bundle adjustment"); - t = getTickCount(); BundleAdjuster adjuster(ba_space, conf_thresh); adjuster(features, pairwise_matches, cameras); - LOGLN("Bundle adjustment, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); // Find median focal length vector focals; @@ -456,15 +452,12 @@ int main(int argc, char* argv[]) if (wave_correct) { - LOGLN("Wave correcting..."); - t = getTickCount(); vector rmats; for (size_t i = 0; i < cameras.size(); ++i) rmats.push_back(cameras[i].R); waveCorrect(rmats); for (size_t i = 0; i < cameras.size(); ++i) cameras[i].R = rmats[i]; - LOGLN("Wave correcting, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); } LOGLN("Warping images (auxiliary)... "); @@ -501,17 +494,11 @@ int main(int argc, char* argv[]) LOGLN("Warping images, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); - LOGLN("Exposure compensation (feed)..."); - t = getTickCount(); Ptr compensator = ExposureCompensator::createDefault(expos_comp_type); compensator->feed(corners, images_warped, masks_warped); - LOGLN("Exposure compensation (feed), time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); - LOGLN("Finding seams..."); - t = getTickCount(); Ptr seam_finder = SeamFinder::createDefault(seam_find_type); seam_finder->find(images_warped_f, corners, masks_warped); - LOGLN("Finding seams, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); // Release unused memory images.clear(); @@ -612,7 +599,7 @@ int main(int argc, char* argv[]) { FeatherBlender* fb = dynamic_cast(static_cast(blender)); fb->setSharpness(1.f/blend_width); - LOGLN("Feather blender, number of bands: " << fb->sharpness()); + LOGLN("Feather blender, sharpness: " << fb->sharpness()); } blender->prepare(corners, sizes); } diff --git a/modules/stitching/motion_estimators.cpp b/modules/stitching/motion_estimators.cpp index 56aa4d1f57..8387bd8593 100644 --- a/modules/stitching/motion_estimators.cpp +++ b/modules/stitching/motion_estimators.cpp @@ -107,6 +107,9 @@ struct CalcRotation void HomographyBasedEstimator::estimate(const vector &features, const vector &pairwise_matches, vector &cameras) { + LOGLN("Estimating rotations..."); + int64 t = getTickCount(); + const int num_images = static_cast(features.size()); #if 0 @@ -142,6 +145,8 @@ void HomographyBasedEstimator::estimate(const vector &features, c vector span_tree_centers; findMaxSpanningTree(num_images, pairwise_matches, span_tree, span_tree_centers); span_tree.walkBreadthFirst(span_tree_centers[0], CalcRotation(num_images, pairwise_matches, cameras)); + + LOGLN("Estimating rotations, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); } @@ -150,6 +155,12 @@ void HomographyBasedEstimator::estimate(const vector &features, c void BundleAdjuster::estimate(const vector &features, const vector &pairwise_matches, vector &cameras) { + if (cost_space_ == NO) + return; + + LOG("Bundle adjustment"); + int64 t = getTickCount(); + num_images_ = static_cast(features.size()); features_ = &features[0]; pairwise_matches_ = &pairwise_matches[0]; @@ -251,6 +262,8 @@ void BundleAdjuster::estimate(const vector &features, const vecto Mat R_inv = cameras[span_tree_centers[0]].R.inv(); for (int i = 0; i < num_images_; ++i) cameras[i].R = R_inv * cameras[i].R; + + LOGLN("Bundle adjustment, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); } @@ -306,7 +319,7 @@ void BundleAdjuster::calcError(Mat &err) p2.x * R2[3] + p2.y * R2[4] + p2.z * R2[5], p2.x * R2[6] + p2.y * R2[7] + p2.z * R2[8]); - double mult = 1; + double mult = 1; // For cost_space_ == RAY_SPACE if (cost_space_ == FOCAL_RAY_SPACE) mult = sqrt(f1 * f2); err.at(3 * match_idx, 0) = mult * (d1.x - d2.x); @@ -374,6 +387,9 @@ void BundleAdjuster::calcJacobian() void waveCorrect(vector &rmats) { + LOGLN("Wave correcting..."); + int64 t = getTickCount(); + float data[9]; Mat r0(1, 3, CV_32F, data); Mat r1(1, 3, CV_32F, data + 3); @@ -403,6 +419,8 @@ void waveCorrect(vector &rmats) for (size_t i = 0; i < rmats.size(); ++i) rmats[i] = R * rmats[i]; + + LOGLN("Wave correcting, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); } diff --git a/modules/stitching/motion_estimators.hpp b/modules/stitching/motion_estimators.hpp index 369f7254a4..bb121b52b0 100644 --- a/modules/stitching/motion_estimators.hpp +++ b/modules/stitching/motion_estimators.hpp @@ -90,7 +90,7 @@ private: class BundleAdjuster : public Estimator { public: - enum { RAY_SPACE, FOCAL_RAY_SPACE }; + enum { NO, RAY_SPACE, FOCAL_RAY_SPACE }; BundleAdjuster(int cost_space = FOCAL_RAY_SPACE, float conf_thresh = 1.f) : cost_space_(cost_space), conf_thresh_(conf_thresh) {} diff --git a/modules/stitching/seam_finders.cpp b/modules/stitching/seam_finders.cpp index efcd86ed8e..c9d28678a3 100644 --- a/modules/stitching/seam_finders.cpp +++ b/modules/stitching/seam_finders.cpp @@ -64,6 +64,9 @@ Ptr SeamFinder::createDefault(int type) void PairwiseSeamFinder::find(const vector &src, const vector &corners, vector &masks) { + LOGLN("Finding seams..."); + int64 t = getTickCount(); + if (src.size() == 0) return; @@ -80,6 +83,8 @@ void PairwiseSeamFinder::find(const vector &src, const vector &corne findInPair(i, j, roi); } } + + LOGLN("Finding seams, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec"); }