Skip to content

Commit 9ade2d1

Browse files
author
Fabien Servant
committed
DepthMap based priors in sfm
1 parent 3e3b309 commit 9ade2d1

21 files changed

+629
-85
lines changed

src/aliceVision/sfm/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set(sfm_files_headers
2727
pipeline/bootstrapping/EstimateAngle.hpp
2828
pipeline/bootstrapping/PairsScoring.hpp
2929
pipeline/bootstrapping/Bootstrap.hpp
30+
pipeline/bootstrapping/TracksDepths.hpp
3031
pipeline/expanding/SfmTriangulation.hpp
3132
pipeline/expanding/SfmResection.hpp
3233
pipeline/expanding/SfmBundle.hpp
@@ -71,6 +72,7 @@ set(sfm_files_sources
7172
pipeline/bootstrapping/EstimateAngle.cpp
7273
pipeline/bootstrapping/PairsScoring.cpp
7374
pipeline/bootstrapping/Bootstrap.cpp
75+
pipeline/bootstrapping/TracksDepths.cpp
7476
pipeline/expanding/SfmTriangulation.cpp
7577
pipeline/expanding/SfmResection.cpp
7678
pipeline/expanding/SfmBundle.cpp

src/aliceVision/sfm/pipeline/bootstrapping/Bootstrap.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <aliceVision/track/tracksUtils.hpp>
99
#include <aliceVision/multiview/triangulation/triangulationDLT.hpp>
1010
#include <aliceVision/sfm/pipeline/expanding/SfmResection.hpp>
11+
#include <aliceVision/sfm/pipeline/bootstrapping/TracksDepths.hpp>
1112
#include <vector>
1213
#include <random>
1314

@@ -166,5 +167,96 @@ bool bootstrapMesh(sfmData::SfMData & sfmData,
166167
return true;
167168
}
168169

170+
bool bootstrapDepth(sfmData::SfMData & sfmData,
171+
const IndexT referenceViewId,
172+
const IndexT nextViewId,
173+
const track::TracksMap& tracksMap,
174+
const track::TracksPerView & tracksPerView)
175+
{
176+
std::mt19937 randomNumberGenerator;
177+
178+
const sfmData::View & viewReference = sfmData.getView(referenceViewId);
179+
const sfmData::View & viewNext = sfmData.getView(nextViewId);
180+
181+
camera::IntrinsicBase::sptr camReference = sfmData.getIntrinsicSharedPtr(viewReference.getIntrinsicId());
182+
camera::IntrinsicBase::sptr camNext = sfmData.getIntrinsicSharedPtr(viewNext.getIntrinsicId());
183+
184+
sfmData::CameraPose & poseReference = sfmData.getPoses()[viewReference.getPoseId()];
185+
sfmData::CameraPose & poseNext = sfmData.getPoses()[viewNext.getPoseId()];
186+
187+
188+
sfmData::SfMData miniSfm;
189+
if (!buildSfmDataFromDepthMap(miniSfm, sfmData, tracksMap, tracksPerView, referenceViewId))
190+
{
191+
return EXIT_FAILURE;
192+
}
193+
194+
sfm::SfmResection resection(50000, std::numeric_limits<double>::infinity());
195+
196+
Eigen::Matrix4d pose;
197+
double newThreshold;
198+
size_t inliersCount;
199+
200+
if (!resection.processView(miniSfm,
201+
tracksMap, tracksPerView,
202+
randomNumberGenerator,
203+
nextViewId, pose, newThreshold, inliersCount))
204+
{
205+
return EXIT_FAILURE;
206+
}
207+
208+
209+
geometry::Pose3 pose3(pose);
210+
poseNext.setTransform(pose3);
211+
212+
const auto & landmarks = miniSfm.getLandmarks();
213+
auto & outLandmarks = sfmData.getLandmarks();
214+
215+
for (const auto & [landmarkId, landmark] : landmarks)
216+
{
217+
//Retrieve track object
218+
const auto & track = tracksMap.at(landmarkId);
219+
220+
const track::TrackItem & itemReference = track.featPerView.at(referenceViewId);
221+
222+
//Maybe this track is not observed in the next view
223+
if (track.featPerView.find(nextViewId) == track.featPerView.end())
224+
{
225+
continue;
226+
}
227+
228+
//Compute error
229+
const track::TrackItem & item = track.featPerView.at(nextViewId);
230+
const Vec2 pt = item.coords;
231+
const Vec2 estpt = camNext->transformProject(pose3, landmark.X.homogeneous(), true);
232+
double err = (pt - estpt).norm();
233+
234+
//If error is ok, then we add it to the sfmData
235+
if (err <= newThreshold)
236+
{
237+
sfmData::Observation obs;
238+
obs.setFeatureId(item.featureId);
239+
obs.setScale(item.scale);
240+
obs.setCoordinates(item.coords);
241+
242+
sfmData::Observation obsReference;
243+
obsReference.setFeatureId(itemReference.featureId);
244+
obsReference.setScale(itemReference.scale);
245+
obsReference.setCoordinates(itemReference.coords);
246+
247+
//Add landmark to sfmData
248+
outLandmarks[landmarkId] = landmark;
249+
outLandmarks[landmarkId].setParallaxRobust(true);
250+
251+
//Add observation to landmark
252+
sfmData::Observations & observations = outLandmarks[landmarkId].getObservations();
253+
observations[referenceViewId] = obsReference;
254+
observations[nextViewId] = obs;
255+
}
256+
}
257+
258+
return true;
259+
}
260+
169261
}
170262
}

src/aliceVision/sfm/pipeline/bootstrapping/Bootstrap.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,21 @@ bool bootstrapMesh(sfmData::SfMData & sfmData,
4646
const track::TracksMap& tracksMap,
4747
const track::TracksPerView & tracksPerView);
4848

49+
50+
/**
51+
* @brief Create a minimal SfmData with poses and landmarks for two views
52+
* @param sfmData the input sfmData which contains camera information
53+
* @param referenceViewId the reference view id
54+
* @param otherViewId the other view id
55+
* @param otherTreference the relative pose
56+
* @param tracksMap the input map of tracks
57+
* @param tracksPerView tracks grouped by views
58+
* @return true
59+
*/
60+
bool bootstrapDepth(sfmData::SfMData & sfmData,
61+
const IndexT referenceViewId,
62+
const IndexT otherViewId,
63+
const track::TracksMap& tracksMap,
64+
const track::TracksPerView & tracksPerView);
4965
}
5066
}

src/aliceVision/sfm/pipeline/bootstrapping/PairsScoring.cpp

Lines changed: 101 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,62 +8,27 @@
88
#include <aliceVision/sfm/pipeline/bootstrapping/EstimateAngle.hpp>
99
#include <aliceVision/sfm/pipeline/expanding/ExpansionPolicyLegacy.hpp>
1010
#include <aliceVision/multiview/triangulation/triangulationDLT.hpp>
11+
#include <aliceVision/sfm/pipeline/bootstrapping/TracksDepths.hpp>
12+
#include <aliceVision/sfm/pipeline/expanding/SfmResection.hpp>
1113

1214
namespace aliceVision {
1315
namespace sfm {
1416

15-
IndexT findBestPair(const sfmData::SfMData & sfmData,
17+
sfm::ReconstructedPair findBestPair(const sfmData::SfMData & sfmData,
1618
const std::vector<sfm::ReconstructedPair> & pairs,
1719
const track::TracksMap& tracksMap,
1820
const track::TracksPerView & tracksPerView,
19-
const std::set<IndexT> & filterIn,
20-
const std::set<IndexT> & filterOut,
2121
double hardMinAngle,
2222
double softMinAngle,
2323
double maxAngle)
2424
{
25-
IndexT bestPair = UndefinedIndexT;
25+
sfm::ReconstructedPair bestPair;
26+
bestPair.reference = UndefinedIndexT;
2627
double maxScore = std::numeric_limits<double>::lowest();
2728

2829
for (IndexT pairId = 0; pairId < pairs.size(); pairId++)
2930
{
3031
const sfm::ReconstructedPair & pair = pairs[pairId];
31-
32-
if (!filterIn.empty())
33-
{
34-
bool found = false;
35-
36-
for (auto item : filterIn)
37-
{
38-
if (pair.reference == item || pair.next == item)
39-
{
40-
found = true;
41-
}
42-
}
43-
44-
if (!found)
45-
{
46-
continue;
47-
}
48-
}
49-
50-
if (!filterOut.empty())
51-
{
52-
bool found = false;
53-
54-
for (auto item : filterOut)
55-
{
56-
if (pair.reference == item || pair.next == item)
57-
{
58-
found = true;
59-
}
60-
}
61-
62-
if (found)
63-
{
64-
continue;
65-
}
66-
}
6732

6833
double angle = 0.0;
6934
std::vector<size_t> usedTracks;
@@ -103,12 +68,107 @@ IndexT findBestPair(const sfmData::SfMData & sfmData,
10368
if (score > maxScore)
10469
{
10570
maxScore = score;
106-
bestPair = pairId;
71+
bestPair = pair;
10772
}
10873
}
10974

11075
return bestPair;
11176
}
11277

78+
sfm::ReconstructedPair findBestPairFromTrackDepths(const sfmData::SfMData & sfmData,
79+
const std::vector<sfm::ReconstructedPair> & pairs,
80+
const track::TracksMap& tracksMap,
81+
const track::TracksPerView & tracksPerView)
82+
{
83+
std::mt19937 randomNumberGenerator;
84+
85+
std::set<IndexT> views;
86+
for (IndexT pairId = 0; pairId < pairs.size(); pairId++)
87+
{
88+
views.insert(pairs[pairId].reference);
89+
views.insert(pairs[pairId].next);
90+
}
91+
92+
sfm::ReconstructedPair bestPair;
93+
bestPair.reference = UndefinedIndexT;
94+
95+
size_t bestCount = 0;
96+
97+
for (const auto & idView: views)
98+
{
99+
sfmData::SfMData miniSfm;
100+
if (!buildSfmDataFromDepthMap(miniSfm, sfmData, tracksMap, tracksPerView, idView))
101+
{
102+
continue;
103+
}
104+
105+
sfm::SfmResection resection(1024, std::numeric_limits<double>::infinity());
106+
107+
108+
sfm::ReconstructedPair bestPairLocal;
109+
size_t maxInliers = 0;
110+
size_t totalInliers = 0;
111+
112+
for (IndexT pairId = 0; pairId < pairs.size(); pairId++)
113+
{
114+
const auto & pairSource = pairs[pairId];
115+
sfm::ReconstructedPair pair;
116+
pair.reference = idView;
117+
118+
if (pairSource.reference == idView)
119+
{
120+
pair.next = pairSource.next;
121+
}
122+
else if (pairSource.next == idView)
123+
{
124+
pair.next = pairSource.reference;
125+
}
126+
else
127+
{
128+
continue;
129+
}
130+
131+
if (miniSfm.getViews().find(pair.next) == miniSfm.getViews().end())
132+
{
133+
continue;
134+
}
135+
136+
Eigen::Matrix4d pose;
137+
double newThreshold;
138+
size_t inliersCount;
139+
140+
if (!resection.processView(miniSfm,
141+
tracksMap,
142+
tracksPerView,
143+
randomNumberGenerator,
144+
pair.next,
145+
pose, newThreshold, inliersCount))
146+
{
147+
continue;
148+
}
149+
150+
pair.pose = geometry::Pose3(pose);
151+
pair.score = inliersCount;
152+
153+
if (inliersCount > maxInliers)
154+
{
155+
maxInliers = inliersCount;
156+
bestPairLocal = pair;
157+
}
158+
159+
totalInliers += inliersCount;
160+
}
161+
162+
if (totalInliers > bestCount)
163+
{
164+
bestPair = bestPairLocal;
165+
bestCount = totalInliers;
166+
}
167+
}
168+
169+
170+
return bestPair;
171+
}
172+
113173
}
114174
}

src/aliceVision/sfm/pipeline/bootstrapping/PairsScoring.hpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,31 @@ namespace sfm {
2020
* @param pairs the input list of reconstructed pairs
2121
* @param tracksMap the input map of tracks
2222
* @param tracksPerView tracks grouped by views
23-
* @param filterIn pair must contains one of the views inside this set (if non empty)
24-
* @param filterout pair must NOT contains one of the views inside this set (if non empty)
2523
* @param hardMinAngle minimal angle allowed (rejected)
2624
* @param softMinAngle minimal angle allowed (tolerated, but heavily downgraded)
2725
* @param maxAngle maximal angle allowed
28-
* @return index in "pairs" of the best pair or UndefinedIndexT if no pair found
26+
* @return The best pair (pair.reference is UndefinedIndexT if nothing found)
2927
*/
30-
IndexT findBestPair(const sfmData::SfMData & sfmData,
31-
const std::vector<sfm::ReconstructedPair> & pairs,
32-
const track::TracksMap& tracksMap,
33-
const track::TracksPerView & tracksPerView,
34-
const std::set<IndexT> & filterIn,
35-
const std::set<IndexT> & filterOut,
36-
double hardMinAngle,
37-
double softMinAngle,
38-
double maxAngle);
28+
sfm::ReconstructedPair findBestPair(const sfmData::SfMData & sfmData,
29+
const std::vector<sfm::ReconstructedPair> & pairs,
30+
const track::TracksMap& tracksMap,
31+
const track::TracksPerView & tracksPerView,
32+
double hardMinAngle,
33+
double softMinAngle,
34+
double maxAngle);
35+
36+
/**
37+
* @brief Get best pair from track Depths with highest score
38+
* @param sfmData the input sfmData which contains camera information
39+
* @param pairs the input list of reconstructed pairs
40+
* @param tracksMap the input map of tracks
41+
* @param tracksPerView tracks grouped by views
42+
* @return The best pair (pair.reference is UndefinedIndexT if nothing found)
43+
*/
44+
sfm::ReconstructedPair findBestPairFromTrackDepths(const sfmData::SfMData & sfmData,
45+
const std::vector<sfm::ReconstructedPair> & pairs,
46+
const track::TracksMap& tracksMap,
47+
const track::TracksPerView & tracksPerView);
3948

4049
}
4150
}

0 commit comments

Comments
 (0)