}
}
- 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];
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<Mat> src_pyr_gauss;
+ vector<Mat> 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<Mat> 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<Mat> weight_pyr_gauss;
- createGaussPyr(weight_map, num_bands_, weight_pyr_gauss);
+ vector<Mat> 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)
{
}
-void createGaussPyr(const Mat &img, int num_layers, vector<Mat> &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<Mat> &pyr_gauss, vector<Mat> &pyr_laplace)
{
if (pyr_gauss.size() == 0)
void createWeightMap(const cv::Mat& mask, float sharpness, cv::Mat& weight);
-void createGaussPyr(const cv::Mat& img, int num_layers, std::vector<cv::Mat>& pyr);
-
void createLaplacePyr(const std::vector<cv::Mat>& pyr_gauss, std::vector<cv::Mat>& pyr_laplace);
// Restores source image in-place. Result will be stored in pyr[0].
vector<string> img_names;\r
vector<Mat> images;\r
bool trygpu = true;\r
- double work_megapix = -1;\r
- double compose_megapix = -1;\r
+ double work_megapix = 1;\r
+ double compose_megapix = 1;\r
int ba_space = BundleAdjuster::FOCAL_RAY_SPACE;\r
float conf_thresh = 1.f;\r
bool wave_correct = true;\r
int blend_type = Blender::MULTI_BAND;\r
string result_name = "result.png";\r
\r
- double work_scale = 1, compose_scale = 1;\r
- bool is_work_scale_set = false, is_compose_scale_set = true;\r
+ double work_scale, compose_scale;\r
+ bool is_work_scale_set = false, is_compose_scale_set = false;\r
\r
if (argc == 1)\r
{\r
else if (string(argv[i]) == "--compose_megapix") \r
{\r
compose_megapix = atof(argv[i + 1]);\r
- is_compose_scale_set = false;\r
i++; \r
}\r
else if (string(argv[i]) == "--result")\r
{\r
if (!is_work_scale_set)\r
{\r
- work_scale = min(1.0, sqrt(work_megapix * 1000000 / full_img.size().area())); \r
+ work_scale = min(1.0, sqrt(work_megapix * 1e6 / full_img.size().area())); \r
is_work_scale_set = true;\r
}\r
Mat img;\r
matcher = BestOf2NearestMatcher(true, match_conf);\r
matcher(images, features, pairwise_matches);\r
\r
- leaveBiggestComponent(images, features, pairwise_matches, conf_thresh);\r
+ vector<int> indices = leaveBiggestComponent(images, features, pairwise_matches, conf_thresh);\r
+ vector<string> img_names_subset;\r
+ for (size_t i = 0; i < indices.size(); ++i)\r
+ img_names_subset.push_back(img_names[indices[i]]);\r
+ img_names = img_names_subset;\r
\r
num_images = static_cast<int>(images.size());\r
if (num_images < 2)\r
nth_element(focals.begin(), focals.end(), focals.begin() + focals.size() / 2);\r
float camera_focal = static_cast<float>(focals[focals.size() / 2]);\r
\r
- if (work_megapix > 0 || compose_megapix > 0)\r
+ if ((work_megapix > 0 || compose_megapix > 0) \r
+ && abs(work_megapix - compose_megapix) > 1e-3)\r
{\r
for (int i = 0; i < num_images; ++i)\r
{\r
Mat full_img = imread(img_names[i]);\r
if (!is_compose_scale_set)\r
{\r
- compose_scale = min(1.0, sqrt(compose_megapix * 1000000 / full_img.size().area())); \r
+ compose_scale = min(1.0, sqrt(compose_megapix * 1e6 / full_img.size().area())); \r
is_compose_scale_set = true;\r
}\r
Mat img;\r
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)
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];
//////////////////////////////////////////////////////////////////////////////
-void leaveBiggestComponent(vector<Mat> &images, vector<ImageFeatures> &features,
- vector<MatchesInfo> &pairwise_matches, float conf_threshold)
+vector<int> leaveBiggestComponent(vector<Mat> &images, vector<ImageFeatures> &features,
+ vector<MatchesInfo> &pairwise_matches, float conf_threshold)
{
const int num_images = static_cast<int>(images.size());
}
if (static_cast<int>(images_subset.size()) == num_images)
- return;
+ return indices;
LOG("Removed some images, because can't match them: (");
LOG(indices_removed[0]);
images = images_subset;
features = features_subset;
pairwise_matches = pairwise_matches_subset;
+
+ return indices;
}
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
-void leaveBiggestComponent(std::vector<cv::Mat> &images, std::vector<ImageFeatures> &features,
- std::vector<MatchesInfo> &pairwise_matches, float conf_threshold);
+std::vector<int> leaveBiggestComponent(std::vector<cv::Mat> &images, std::vector<ImageFeatures> &features,
+ std::vector<MatchesInfo> &pairwise_matches, float conf_threshold);
void findMaxSpanningTree(int num_images, const std::vector<MatchesInfo> &pairwise_matches,
Graph &span_tree, std::vector<int> ¢ers);