MVE - Multi-View Environment mve-devel
Loading...
Searching...
No Matches
local_view_selection.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015, Simon Fuhrmann
3 * TU Darmstadt - Graphics, Capture and Massively Parallel Computing
4 * All rights reserved.
5 *
6 * This software may be modified and distributed under the terms
7 * of the BSD 3-Clause license. See the LICENSE.txt file for details.
8 */
9
10#include "math/defines.h"
11#include "math/functions.h"
13#include "dmrecon/mvs_tools.h"
15#include "dmrecon/settings.h"
16
18
19LocalViewSelection::LocalViewSelection(
20 std::vector<SingleView::Ptr> const& views,
21 Settings const& settings,
22 IndexSet const& globalViewIDs,
23 IndexSet const& propagated,
24 PatchSampler::Ptr sampler)
25 :
26 ViewSelection(settings),
27 success(false),
28 views(views),
29 sampler(sampler)
30{
31 // inherited attribute
32 this->selected = propagated;
33
34 if (!sampler->success[settings.refViewNr]) {
35 return;
36 }
38 success = true;
39 else if (selected.size() > settings.nrReconNeighbors) {
40 std::cerr << "ERROR: Too many local neighbors propagated!" << std::endl;
41 selected.clear();
42 }
43
44 available.clear();
45 available.resize(views.size(), false);
46 IndexSet::const_iterator id;
47 for (id = globalViewIDs.begin(); id != globalViewIDs.end(); ++id) {
48 available[*id] = true;
49 }
50 IndexSet::const_iterator sel;
51 for (sel = selected.begin(); sel != selected.end(); ++sel) {
52 available[*sel] = false;
53 }
54}
55
56void
58{
59 if (selected.size() == settings.nrReconNeighbors) {
60 success = true;
61 return;
62 }
64
65 math::Vec3f p(sampler->getMidWorldPoint());
66 // pixel print in reference view
67 float mfp = refV->footPrintScaled(p);
68 math::Vec3f refDir = (p - refV->camPos).normalized();
69 std::map<std::size_t, math::Vec3f> viewDir;
70 std::map<std::size_t, math::Vec3f> epipolarPlane; // plane normal
71 std::map<std::size_t, float> ncc;
72
73 for (std::size_t i = 0; i < views.size(); ++i) {
74 if (!available[i])
75 continue;
76 float tmpNCC = sampler->getFastNCC(i);
77 assert(!MATH_ISNAN(tmpNCC));
78 if (tmpNCC < settings.minNCC) {
79 available[i] = false;
80 continue;
81 }
82 ncc[i] = tmpNCC;
83 viewDir[i] = (p - views[i]->camPos).normalized();
84 epipolarPlane[i] = (viewDir[i].cross(refDir)).normalized();
85 }
86 IndexSet::const_iterator sel;
87 for (sel = selected.begin(); sel != selected.end(); ++sel) {
88 viewDir[*sel] = (p - views[*sel]->camPos).normalized();
89 epipolarPlane[*sel] = (viewDir[*sel].cross(refDir)).normalized();
90 }
91
92 bool foundOne = true;
93 while (selected.size() < settings.nrReconNeighbors && foundOne)
94 {
95 foundOne = false;
96 std::size_t maxView = 0;
97 float maxScore = 0.f;
98 for (std::size_t i = 0; i < views.size(); ++i) {
99 if (!available[i])
100 continue;
101 float score = ncc[i];
102
103 // resolution difference
104 float nfp = views[i]->footPrint(p);
105 if (mfp / nfp < 0.5f) {
106 score *= 0.01f;
107 }
108
109 // parallax w.r.t. reference view
110 float dp = math::clamp(refDir.dot(viewDir[i]), -1.f, 1.f);
111 float plx = std::acos(dp) * 180.f / pi;
112 score *= parallaxToWeight(plx);
113 assert(!MATH_ISNAN(score));
114
115 for (sel = selected.begin(); sel != selected.end(); ++sel) {
116 // parallax w.r.t. other selected views
117 dp = math::clamp(viewDir[*sel].dot(viewDir[i]), -1.f, 1.f);
118 plx = std::acos(dp) * 180.f / pi;
119 score *= parallaxToWeight(plx);
120
121 // epipolar geometry
122 dp = epipolarPlane[i].dot(epipolarPlane[*sel]);
123 dp = math::clamp(dp, -1.f, 1.f);
124 float angle = std::abs(std::acos(dp) * 180.f / pi);
125 if (angle > 90.f)
126 angle = 180.f - angle;
127
128 angle = std::max(angle, 1.f);
129 if (angle < settings.minParallax)
130 score *= angle / settings.minParallax;
131 assert(!MATH_ISNAN(score));
132 }
133 if (score > maxScore) {
134 foundOne = true;
135 maxScore = score;
136 maxView = i;
137 }
138 }
139 if (foundOne) {
140 selected.insert(maxView);
141 available[maxView] = false;
142 }
143 }
144 if (selected.size() == settings.nrReconNeighbors) {
145 success = true;
146 }
147}
148
149void
151{
152 IndexSet::const_iterator tbr = toBeReplaced.begin();
153 while (tbr != toBeReplaced.end()) {
154 available[*tbr] = false;
155 selected.erase(*tbr);
156 ++tbr;
157 }
158 success = false;
159 performVS();
160}
161
162
Vector class for arbitrary dimensions and types.
Definition vector.h:87
T dot(Vector< T, N > const &other) const
Dot (or scalar) product between self and another vector.
Definition vector.h:542
void replaceViews(IndexSet const &toBeReplaced)
std::shared_ptr< PatchSampler > Ptr
std::shared_ptr< SingleView > Ptr
Definition single_view.h:31
Settings const & settings
std::vector< bool > available
#define MVS_NAMESPACE_BEGIN
Definition defines.h:18
#define MVS_NAMESPACE_END
Definition defines.h:19
#define MATH_ISNAN(x)
Definition defines.h:104
T const & clamp(T const &v, T const &min=T(0), T const &max=T(1))
Returns value 'v' clamped to the interval specified by 'min' and 'max'.
Definition functions.h:204
std::set< std::size_t > IndexSet
Definition defines.h:24
float parallaxToWeight(float p)
Turns a parallax value (0 <= p <= 180) into a weight according to a bilateral Gaussian (see [Furukawa...
Definition mvs_tools.h:56
const float pi
Definition defines.h:28
unsigned int nrReconNeighbors
Definition settings.h:37
float minNCC
Definition settings.h:32
std::size_t refViewNr
The reference view ID to reconstruct.
Definition settings.h:25
float minParallax
Definition settings.h:33