From 4567b4326bc3f7fc6550dfac447fa9d07890b879 Mon Sep 17 00:00:00 2001 From: Alexey Spizhevoy Date: Wed, 18 May 2011 14:52:23 +0000 Subject: [PATCH] reduced memory requirements in opencv_stitching --- modules/stitching/autocalib.cpp | 2 +- modules/stitching/blenders.cpp | 30 +++++++++---------------- modules/stitching/blenders.hpp | 2 -- modules/stitching/main.cpp | 22 ++++++++++-------- modules/stitching/motion_estimators.cpp | 14 ++++++------ modules/stitching/motion_estimators.hpp | 4 ++-- 6 files changed, 34 insertions(+), 40 deletions(-) diff --git a/modules/stitching/autocalib.cpp b/modules/stitching/autocalib.cpp index ad1ac0a0a7..ecededd9ea 100644 --- a/modules/stitching/autocalib.cpp +++ b/modules/stitching/autocalib.cpp @@ -56,7 +56,7 @@ double estimateFocal(const vector &images, const vector &/*f } } - if (focals.size() + 1 >= images.size()) + if (focals.size() >= 2 * (num_images - 1)) { nth_element(focals.begin(), focals.end(), focals.begin() + focals.size()/2); return focals[focals.size()/2]; diff --git a/modules/stitching/blenders.cpp b/modules/stitching/blenders.cpp index 4ca8fc38ec..04cc7b98a4 100644 --- a/modules/stitching/blenders.cpp +++ b/modules/stitching/blenders.cpp @@ -133,19 +133,20 @@ Point MultiBandBlender::blend(const vector &src, const vector &corne int left = corners[img_idx].x - dst_roi.x; int right = dst_roi.br().x - corners[img_idx].x - src[img_idx].cols; - Mat big_src; - copyMakeBorder(src[img_idx], big_src, top, bottom, left, right, BORDER_REFLECT); - vector src_pyr_gauss; + vector src_pyr_gauss(num_bands_ + 1); + copyMakeBorder(src[img_idx], src_pyr_gauss[0], top, bottom, left, right, BORDER_REFLECT); + for (int i = 0; i < num_bands_; ++i) + pyrDown(src_pyr_gauss[i], src_pyr_gauss[i + 1]); + vector src_pyr_laplace; - createGaussPyr(big_src, num_bands_, src_pyr_gauss); createLaplacePyr(src_pyr_gauss, src_pyr_laplace); - Mat big_mask; - copyMakeBorder(masks[img_idx], big_mask, top, bottom, left, right, BORDER_CONSTANT); - Mat weight_map; - big_mask.convertTo(weight_map, CV_32F, 1./255.); - vector weight_pyr_gauss; - createGaussPyr(weight_map, num_bands_, weight_pyr_gauss); + vector weight_pyr_gauss(num_bands_ + 1); + Mat mask_f; + masks[img_idx].convertTo(mask_f, CV_32F, 1./255.); + copyMakeBorder(mask_f, weight_pyr_gauss[0], top, bottom, left, right, BORDER_CONSTANT); + for (int i = 0; i < num_bands_; ++i) + pyrDown(weight_pyr_gauss[i], weight_pyr_gauss[i + 1]); for (int band_idx = 0; band_idx <= num_bands_; ++band_idx) { @@ -286,15 +287,6 @@ void createWeightMap(const Mat &mask, float sharpness, Mat &weight) } -void createGaussPyr(const Mat &img, int num_layers, vector &pyr) -{ - pyr.resize(num_layers + 1); - pyr[0] = img.clone(); - for (int i = 0; i < num_layers; ++i) - pyrDown(pyr[i], pyr[i + 1]); -} - - void createLaplacePyr(const vector &pyr_gauss, vector &pyr_laplace) { if (pyr_gauss.size() == 0) diff --git a/modules/stitching/blenders.hpp b/modules/stitching/blenders.hpp index a2151b647a..ae1b6b3716 100644 --- a/modules/stitching/blenders.hpp +++ b/modules/stitching/blenders.hpp @@ -63,8 +63,6 @@ void normalize(const cv::Mat& weight, cv::Mat& src); void createWeightMap(const cv::Mat& mask, float sharpness, cv::Mat& weight); -void createGaussPyr(const cv::Mat& img, int num_layers, std::vector& pyr); - void createLaplacePyr(const std::vector& pyr_gauss, std::vector& pyr_laplace); // Restores source image in-place. Result will be stored in pyr[0]. diff --git a/modules/stitching/main.cpp b/modules/stitching/main.cpp index 83d01a659e..bbdf701538 100644 --- a/modules/stitching/main.cpp +++ b/modules/stitching/main.cpp @@ -35,8 +35,8 @@ int main(int argc, char* argv[]) vector img_names; vector images; bool trygpu = true; - double work_megapix = -1; - double compose_megapix = -1; + double work_megapix = 1; + double compose_megapix = 1; int ba_space = BundleAdjuster::FOCAL_RAY_SPACE; float conf_thresh = 1.f; bool wave_correct = true; @@ -47,8 +47,8 @@ int main(int argc, char* argv[]) int blend_type = Blender::MULTI_BAND; string result_name = "result.png"; - double work_scale = 1, compose_scale = 1; - bool is_work_scale_set = false, is_compose_scale_set = true; + double work_scale, compose_scale; + bool is_work_scale_set = false, is_compose_scale_set = false; if (argc == 1) { @@ -85,7 +85,6 @@ int main(int argc, char* argv[]) else if (string(argv[i]) == "--compose_megapix") { compose_megapix = atof(argv[i + 1]); - is_compose_scale_set = false; i++; } else if (string(argv[i]) == "--result") @@ -195,7 +194,7 @@ int main(int argc, char* argv[]) { if (!is_work_scale_set) { - work_scale = min(1.0, sqrt(work_megapix * 1000000 / full_img.size().area())); + work_scale = min(1.0, sqrt(work_megapix * 1e6 / full_img.size().area())); is_work_scale_set = true; } Mat img; @@ -224,7 +223,11 @@ int main(int argc, char* argv[]) matcher = BestOf2NearestMatcher(true, match_conf); matcher(images, features, pairwise_matches); - leaveBiggestComponent(images, features, pairwise_matches, conf_thresh); + vector indices = leaveBiggestComponent(images, features, pairwise_matches, conf_thresh); + vector img_names_subset; + for (size_t i = 0; i < indices.size(); ++i) + img_names_subset.push_back(img_names[indices[i]]); + img_names = img_names_subset; num_images = static_cast(images.size()); if (num_images < 2) @@ -271,14 +274,15 @@ int main(int argc, char* argv[]) nth_element(focals.begin(), focals.end(), focals.begin() + focals.size() / 2); float camera_focal = static_cast(focals[focals.size() / 2]); - if (work_megapix > 0 || compose_megapix > 0) + if ((work_megapix > 0 || compose_megapix > 0) + && abs(work_megapix - compose_megapix) > 1e-3) { for (int i = 0; i < num_images; ++i) { Mat full_img = imread(img_names[i]); if (!is_compose_scale_set) { - compose_scale = min(1.0, sqrt(compose_megapix * 1000000 / full_img.size().area())); + compose_scale = min(1.0, sqrt(compose_megapix * 1e6 / full_img.size().area())); is_compose_scale_set = true; } Mat img; diff --git a/modules/stitching/motion_estimators.cpp b/modules/stitching/motion_estimators.cpp index 90638fd001..ae72b71387 100644 --- a/modules/stitching/motion_estimators.cpp +++ b/modules/stitching/motion_estimators.cpp @@ -328,8 +328,7 @@ void waveCorrect(vector &rmats) SVD svd; svd(cov, SVD::FULL_UV); svd.vt.row(2).copyTo(r1); - if (determinant(svd.vt) < 0) - r1 *= -1; + if (determinant(svd.vt) < 0) r1 *= -1; Mat avgz = Mat::zeros(3, 1, CV_32F); for (size_t i = 0; i < rmats.size(); ++i) @@ -338,8 +337,7 @@ void waveCorrect(vector &rmats) normalize(r0, r0); r1.cross(r0).copyTo(r2); - if (determinant(R) < 0) - R *= -1; + if (determinant(R) < 0) R *= -1; for (size_t i = 0; i < rmats.size(); ++i) rmats[i] = R * rmats[i]; @@ -348,8 +346,8 @@ void waveCorrect(vector &rmats) ////////////////////////////////////////////////////////////////////////////// -void leaveBiggestComponent(vector &images, vector &features, - vector &pairwise_matches, float conf_threshold) +vector leaveBiggestComponent(vector &images, vector &features, + vector &pairwise_matches, float conf_threshold) { const int num_images = static_cast(images.size()); @@ -393,7 +391,7 @@ void leaveBiggestComponent(vector &images, vector &features, } if (static_cast(images_subset.size()) == num_images) - return; + return indices; LOG("Removed some images, because can't match them: ("); LOG(indices_removed[0]); @@ -403,6 +401,8 @@ void leaveBiggestComponent(vector &images, vector &features, images = images_subset; features = features_subset; pairwise_matches = pairwise_matches_subset; + + return indices; } diff --git a/modules/stitching/motion_estimators.hpp b/modules/stitching/motion_estimators.hpp index 3a782a297f..3bc3f74af1 100644 --- a/modules/stitching/motion_estimators.hpp +++ b/modules/stitching/motion_estimators.hpp @@ -83,8 +83,8 @@ void waveCorrect(std::vector &rmats); ////////////////////////////////////////////////////////////////////////////// // Auxiliary functions -void leaveBiggestComponent(std::vector &images, std::vector &features, - std::vector &pairwise_matches, float conf_threshold); +std::vector leaveBiggestComponent(std::vector &images, std::vector &features, + std::vector &pairwise_matches, float conf_threshold); void findMaxSpanningTree(int num_images, const std::vector &pairwise_matches, Graph &span_tree, std::vector ¢ers);