Skip to content

Commit a8d113a

Browse files
committed
[filterSfM] add new landmark filtering option
filter unstable landmarks that have an insufficient number of observations (specified as a parameter)
1 parent a88495a commit a8d113a

File tree

1 file changed

+52
-15
lines changed

1 file changed

+52
-15
lines changed

src/software/pipeline/main_filterSfM.cpp

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,50 @@ class PixSizeSearch
120120
inline double worstDist() const { return _radius_sq; }
121121
};
122122

123-
bool filterLandmarks(SfMData& sfmData, double radiusScale, bool useFeatureScale)
123+
bool filterLandmarks(SfMData& sfmData, double radiusScale, bool useFeatureScale, int minNbObservationsPerLandmark)
124124
{
125-
std::vector<Landmark> landmarksData(sfmData.getLandmarks().size());
125+
const auto initialNbLandmarks = sfmData.getLandmarks().size();
126+
std::vector<Landmark> landmarksData(initialNbLandmarks);
126127
{
127128
size_t i = 0;
128-
for(const auto& it : sfmData.getLandmarks())
129+
if (minNbObservationsPerLandmark > 0)
129130
{
130-
landmarksData[i++] = it.second;
131+
ALICEVISION_LOG_INFO("Removing landmarks having an insufficient number of observations: started.");
132+
for(auto& it : sfmData.getLandmarks())
133+
{
134+
if(it.second.observations.size() < minNbObservationsPerLandmark)
135+
continue;
136+
landmarksData[i++] = it.second;
137+
}
138+
landmarksData.resize(i);
139+
ALICEVISION_LOG_INFO(
140+
"Removed " << (initialNbLandmarks - i) <<
141+
" landmarks out of " << initialNbLandmarks <<
142+
", i.e. " << ((initialNbLandmarks - i) * 100.f / initialNbLandmarks) <<
143+
" % "
144+
);
145+
ALICEVISION_LOG_INFO("Removing landmarks having an insufficient number of observations: done.");
146+
}
147+
else
148+
{
149+
for(auto& it : sfmData.getLandmarks())
150+
{
151+
landmarksData[i++] = it.second;
152+
}
131153
}
132154
}
133155

156+
if (radiusScale <= 0)
157+
{
158+
std::vector<std::pair<IndexT, Landmark>> filteredLandmarks(landmarksData.size());
159+
for(IndexT newIdx = 0; newIdx < landmarksData.size(); newIdx++)
160+
{
161+
filteredLandmarks[newIdx] = std::make_pair(newIdx, landmarksData[newIdx]);
162+
}
163+
sfmData.getLandmarks() = Landmarks(filteredLandmarks.begin(), filteredLandmarks.end());
164+
return true;
165+
}
166+
134167
mvsUtils::MultiViewParams mp(sfmData, "", "", "", false);
135168
std::vector<double> landmarksPixSize(landmarksData.size());
136169

@@ -168,7 +201,7 @@ bool filterLandmarks(SfMData& sfmData, double radiusScale, bool useFeatureScale)
168201
ALICEVISION_LOG_INFO("KdTree created for " << landmarksData.size() << " points.");
169202
std::vector<bool> toRemove(landmarksData.size(), false);
170203

171-
ALICEVISION_LOG_INFO("Identifying landmarks to remove: started.");
204+
ALICEVISION_LOG_INFO("Identifying landmarks to remove based on pixel size: started.");
172205

173206
size_t nbToRemove = 0;
174207
#pragma omp parallel for reduction(+:nbToRemove)
@@ -184,14 +217,14 @@ bool filterLandmarks(SfMData& sfmData, double radiusScale, bool useFeatureScale)
184217
}
185218

186219
ALICEVISION_LOG_INFO(
187-
"Identified " << (landmarksData.size() - nbToRemove) <<
188-
" landmarks to remove out of " << (landmarksData.size()) <<
189-
", i.e. " << ((landmarksData.size() - nbToRemove) * 100.f / landmarksData.size()) <<
220+
"Identified " << nbToRemove <<
221+
" landmarks to remove out of " << initialNbLandmarks <<
222+
", i.e. " << (nbToRemove * 100.f / initialNbLandmarks) <<
190223
" % "
191224
);
192225
ALICEVISION_LOG_INFO("Identifying landmarks to remove: done.");
193226

194-
ALICEVISION_LOG_INFO("Removing landmarks: started.");
227+
ALICEVISION_LOG_INFO("Removing landmarks based on pixel size: started.");
195228
std::vector<std::pair<IndexT, Landmark>> filteredLandmarks(landmarksData.size() - nbToRemove);
196229
IndexT newIdx = 0;
197230
for (size_t i = 0; i < landmarksData.size(); i++)
@@ -202,7 +235,7 @@ bool filterLandmarks(SfMData& sfmData, double radiusScale, bool useFeatureScale)
202235
}
203236
}
204237
sfmData.getLandmarks() = Landmarks(filteredLandmarks.begin(), filteredLandmarks.end());
205-
ALICEVISION_LOG_INFO("Removing landmarks: done.");
238+
ALICEVISION_LOG_INFO("Removing landmarks based on pixel size: done.");
206239

207240
return true;
208241
}
@@ -270,7 +303,8 @@ int aliceVision_main(int argc, char *argv[])
270303
// std::string verboseLevel = system::EVerboseLevel_enumToString(system::Logger::getDefaultVerboseLevel());
271304
std::string inputSfmFilename;
272305
std::string outputSfmFilename;
273-
int maxNbObservationsPerLandmark = 5;
306+
int maxNbObservationsPerLandmark = 2;
307+
int minNbObservationsPerLandmark = 5;
274308
double radiusScale = 2;
275309
bool useFeatureScale = true;
276310

@@ -290,9 +324,11 @@ int aliceVision_main(int argc, char *argv[])
290324
optionalParams.add_options()
291325
("maxNbObservationsPerLandmark", po::value<int>(&maxNbObservationsPerLandmark)->default_value(maxNbObservationsPerLandmark),
292326
"Maximum number of allowed observations per landmark.")
327+
("minNbObservationsPerLandmark", po::value<int>(&minNbObservationsPerLandmark)->default_value(minNbObservationsPerLandmark),
328+
"Minimum number of observations required to keep a landmark.")
293329
("radiusScale", po::value<double>(&radiusScale)->default_value(radiusScale),
294-
"Scale factor applied to pixel size based radius filter applied to landmarks.")(
295-
"useFeatureScale", po::value<bool>(&useFeatureScale)->default_value(useFeatureScale),
330+
"Scale factor applied to pixel size based radius filter applied to landmarks.")
331+
("useFeatureScale", po::value<bool>(&useFeatureScale)->default_value(useFeatureScale),
296332
"If true, use feature scale for computing pixel size. Otherwise, use a scale of 1 pixel.")
297333
("featuresFolders,f", po::value<std::vector<std::string>>(&featuresFolders)->multitoken(),
298334
"Path to folder(s) containing the extracted features.")
@@ -325,10 +361,11 @@ int aliceVision_main(int argc, char *argv[])
325361
}
326362

327363
// filter SfM data
328-
if(radiusScale > 0)
364+
365+
if(radiusScale > 0 || minNbObservationsPerLandmark > 0)
329366
{
330367
ALICEVISION_LOG_INFO("Filtering landmarks: started.");
331-
filterLandmarks(sfmData, radiusScale, useFeatureScale);
368+
filterLandmarks(sfmData, radiusScale, useFeatureScale, minNbObservationsPerLandmark);
332369
ALICEVISION_LOG_INFO("Filtering landmarks: done.");
333370
}
334371

0 commit comments

Comments
 (0)