Skip to content

Commit 445c8df

Browse files
Merge pull request #2024 from alicevision/fix/tracksMerging
Fix Bug in tracksMerger
2 parents 8458e4d + 76bfbaa commit 445c8df

File tree

3 files changed

+48
-23
lines changed

3 files changed

+48
-23
lines changed

src/aliceVision/sfm/pipeline/expanding/ExpansionProcess.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ void ExpansionProcess::remapExistingLandmarks(sfmData::SfMData & sfmData, const
152152
}
153153

154154
auto landmarkPair = landmarks.find(it->second);
155+
156+
// This should not happen if each feature is associated to only one track
157+
if (landmarkPair == landmarks.end())
158+
{
159+
continue;
160+
}
161+
155162
sfmData::Landmark l = landmarkPair->second;
156163
landmarks.erase(landmarkPair->first);
157164

src/aliceVision/track/TracksMerger.cpp

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,48 @@ namespace track
1313

1414
bool TracksMerger::addTrackMap(const track::TracksMap & inputTracks)
1515
{
16+
// Loop over the tracks to add
1617
for (const auto & [idTrack, track]: inputTracks)
1718
{
18-
IndexT foundTrack = UndefinedIndexT;
19-
size_t newSize = track.featPerView.size();
20-
19+
std::map<IndexT, size_t> candidates;
20+
21+
// Find if one of the features already exists in a track
22+
// In this case we would like to merge both tracks instead of adding a track
2123
for (const auto & [idView, feat]: track.featPerView)
2224
{
2325
TuplePoint tp = std::make_tuple(track.descType, idView, feat.featureId);
24-
auto it = _existingTracks.find(tp);
25-
if (it != _existingTracks.end())
26+
if (_existingTracks.find(tp) == _existingTracks.end())
27+
{
28+
// This feature is not present in the existing tracks
29+
continue;
30+
}
31+
32+
// Compute stats on best target to use
33+
IndexT target = _existingTracks[tp];
34+
if (candidates.find(target) == candidates.end())
35+
{
36+
candidates[target] = _tracks[target].featPerView.size();
37+
}
38+
else
39+
{
40+
candidates[target]++;
41+
}
42+
}
43+
44+
// Select the largest track solution
45+
size_t bestSize = 0;
46+
IndexT foundTrack = UndefinedIndexT;
47+
for (const auto [trackId, size] : candidates)
48+
{
49+
if (size > bestSize)
2650
{
27-
foundTrack = it->second;
28-
break;
51+
foundTrack = trackId;
52+
bestSize = size;
2953
}
3054
}
31-
55+
3256
if (foundTrack == UndefinedIndexT)
33-
{
57+
{
3458
//Simply add track
3559
foundTrack = _lastIndex;
3660
_lastIndex++;
@@ -40,25 +64,18 @@ bool TracksMerger::addTrackMap(const track::TracksMap & inputTracks)
4064
auto & outputTrack = _tracks[foundTrack];
4165
outputTrack.descType = track.descType;
4266

43-
//Previous Size is either 0 if new track, or the size of the matching track
44-
size_t oldSize = outputTrack.featPerView.size();
45-
46-
//Append all features from existing track
67+
// Merge both tracks
4768
for (const auto & [idView, feat]: track.featPerView)
4869
{
4970
TuplePoint tp = std::make_tuple(track.descType, idView, feat.featureId);
50-
_existingTracks[tp] = foundTrack;
51-
52-
// Replace only if the new tracks is longer than the old one.
53-
if (outputTrack.featPerView.find(idView) != outputTrack.featPerView.end())
71+
// Ignore any track item that disagrees with the retargeting
72+
if (_existingTracks.find(tp) != _existingTracks.end())
5473
{
55-
if (newSize < oldSize)
56-
{
57-
continue;
58-
}
59-
}
60-
74+
continue;
75+
}
76+
6177
outputTrack.featPerView[idView] = feat;
78+
_existingTracks[tp] = foundTrack;
6279
}
6380
}
6481

src/aliceVision/track/TracksMerger.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class TracksMerger
2020
public:
2121
//viewId, featureId is a unique identifier for an observation
2222
using TuplePoint = std::tuple<feature::EImageDescriberType, IndexT, std::size_t>;
23+
2324
public:
2425

2526
/**

0 commit comments

Comments
 (0)