@@ -55,8 +55,8 @@ struct LandmarksAdaptator
5555 // / CRTP helper method
5656 inline Derived& derived () { return *static_cast <Derived*>(this ); }
5757
58- const sfmData::Landmarks& _data;
59- LandmarksAdaptator (const sfmData::Landmarks & data)
58+ const std::vector<Landmark> _data;
59+ LandmarksAdaptator (const std::vector<Landmark> & data)
6060 : _data(data)
6161 {
6262 }
@@ -67,9 +67,7 @@ struct LandmarksAdaptator
6767 // Returns the dim'th component of the idx'th point in the class:
6868 inline T kdtree_get_pt (const size_t idx, int dim) const
6969 {
70- auto it = _data.begin ();
71- std::advance (it, idx);
72- return it->second .X (dim);
70+ return _data[idx].X (dim);
7371 }
7472
7573 // Optional bounding-box computation: return false to default to a standard bbox computation loop.
@@ -100,7 +98,7 @@ class PixSizeSearch
10098 const double _pixSize_i;
10199 bool found = false ;
102100
103- inline PixSizeSearch (double radius, const std::vector<double >& pixSize, int i)
101+ inline PixSizeSearch (double radius, const std::vector<double >& pixSize, size_t i)
104102 : _radius_sq(radius * radius)
105103 , _pixSize(pixSize)
106104 , _pixSize_i(pixSize[i])
@@ -124,16 +122,23 @@ class PixSizeSearch
124122
125123bool filterLandmarks (SfMData& sfmData, double radiusScale)
126124{
125+ std::vector<Landmark> landmarksData (sfmData.getLandmarks ().size ());
126+ {
127+ size_t i = 0 ;
128+ for (const auto & it : sfmData.getLandmarks ())
129+ {
130+ landmarksData[i++] = it.second ;
131+ }
132+ }
133+
127134 mvsUtils::MultiViewParams mp (sfmData, " " , " " , " " , false );
128- std::vector<double > landmarksPixSize (sfmData. getLandmarks () .size ());
135+ std::vector<double > landmarksPixSize (landmarksData .size ());
129136
130137 ALICEVISION_LOG_INFO (" Computing pixel size: started." );
131138 #pragma omp parallel for
132- for (auto i = 0 ; i < sfmData. getLandmarks () .size (); i++)
139+ for (auto i = 0 ; i < landmarksData .size (); i++)
133140 {
134- auto landmarkPair = sfmData.getLandmarks ().begin ();
135- std::advance (landmarkPair, i);
136- const sfmData::Landmark& landmark = landmarkPair->second ;
141+ const Landmark& landmark = landmarksData[i];
137142
138143 // compute landmark pixSize
139144 double pixSize = 0 .;
@@ -155,73 +160,66 @@ bool filterLandmarks(SfMData& sfmData, double radiusScale)
155160 // std::stable_sort(landmarksPixSize.begin(), landmarksPixSize.end(), std::greater<>{});
156161
157162 ALICEVISION_LOG_INFO (" Build nanoflann KdTree index." );
158- LandmarksAdaptator data (sfmData. getLandmarks () );
163+ LandmarksAdaptator data (landmarksData );
159164 KdTree tree (3 , data, nanoflann::KDTreeSingleIndexAdaptorParams (MAX_LEAF_ELEMENTS));
160165 tree.buildIndex ();
161- ALICEVISION_LOG_INFO (" KdTree created for " << sfmData.getLandmarks ().size () << " points." );
162- std::vector<IndexT> newIdx (sfmData.getLandmarks ().size ());
163- IndexT currentIdx = 0 ;
166+ ALICEVISION_LOG_INFO (" KdTree created for " << landmarksData.size () << " points." );
167+ std::vector<bool > toRemove (landmarksData.size (), false );
164168
165169 ALICEVISION_LOG_INFO (" Identifying landmarks to remove: started." );
166- #pragma omp parallel for
167- for (auto i = 0 ; i < sfmData.getLandmarks ().size (); i++)
170+
171+ size_t nbToRemove = 0 ;
172+ #pragma omp parallel for reduction(+:nbToRemove)
173+ for (auto i = 0 ; i < landmarksData.size (); i++)
168174 {
169175 PixSizeSearch search (landmarksPixSize[i] * radiusScale, landmarksPixSize, i);
170- bool found = tree.findNeighbors (search, sfmData. getLandmarks (). at (i) .X .data (), nanoflann::SearchParams ());
176+ bool found = tree.findNeighbors (search, landmarksData[i] .X .data (), nanoflann::SearchParams ());
171177 if (found)
172178 {
173- newIdx[i] = -1 ;
174- }
175- else
176- {
177- newIdx[i] = currentIdx++;
179+ toRemove[i] = true ;
180+ nbToRemove++;
178181 }
179182 }
180183
181184 ALICEVISION_LOG_INFO (
182- " Identified " << (sfmData. getLandmarks (). size () - currentIdx ) <<
183- " landmarks to remove out of " << (sfmData. getLandmarks () .size ()) <<
184- " , i.e. " << ((sfmData. getLandmarks (). size () - currentIdx ) * 100 .f / sfmData. getLandmarks () .size ()) <<
185+ " Identified " << (landmarksData. size () - nbToRemove ) <<
186+ " landmarks to remove out of " << (landmarksData .size ()) <<
187+ " , i.e. " << ((landmarksData. size () - nbToRemove ) * 100 .f / landmarksData .size ()) <<
185188 " % "
186189 );
187190 ALICEVISION_LOG_INFO (" Identifying landmarks to remove: done." );
188191
189192 ALICEVISION_LOG_INFO (" Removing landmarks: started." );
190- std::vector<std::pair<IndexT, Landmark>> filteredLandmarks (currentIdx );
191- # pragma omp parallel for
192- for (auto i = 0 ; i < sfmData. getLandmarks () .size (); i++)
193+ std::vector<std::pair<IndexT, Landmark>> filteredLandmarks (landmarksData. size () - nbToRemove );
194+ IndexT newIdx = 0 ;
195+ for (size_t i = 0 ; i < landmarksData .size (); i++)
193196 {
194- if (newIdx [i] != - 1 )
197+ if (!toRemove [i])
195198 {
196- filteredLandmarks[newIdx[i]] = std::make_pair (newIdx[i], sfmData. getLandmarks (). at (i) );
199+ filteredLandmarks[newIdx++] = std::make_pair (newIdx, landmarksData[i] );
197200 }
198201 }
199202 sfmData.getLandmarks () = Landmarks (filteredLandmarks.begin (), filteredLandmarks.end ());
200203 ALICEVISION_LOG_INFO (" Removing landmarks: done." );
201204
202- // // take only best observations
203- // observationScores.resize(maxNbObservationsPerLandmark);
204-
205-
206-
207- // // replace the observations
208- // Observations filteredObservations;
209- // for(auto observationScorePair : observationScores)
210- // {
211- // filteredObservations[observationScorePair.second] = landmark.observations[observationScorePair.second];
212- // }
213- // landmark.observations = filteredObservations;
214205 return true ;
215206}
216207
217208bool filterObservations (SfMData& sfmData, int maxNbObservationsPerLandmark)
218209{
210+ std::vector<Landmark> landmarksData (sfmData.getLandmarks ().size ());
211+ {
212+ size_t i = 0 ;
213+ for (const auto & it : sfmData.getLandmarks ())
214+ {
215+ landmarksData[i++] = it.second ;
216+ }
217+ }
218+
219219 #pragma omp parallel for
220- for (auto i = 0 ; i < sfmData. getLandmarks () .size (); i++)
220+ for (auto i = 0 ; i < landmarksData .size (); i++)
221221 {
222- auto landmarkPair = sfmData.getLandmarks ().begin ();
223- std::advance (landmarkPair, i);
224- sfmData::Landmark& landmark = landmarkPair->second ;
222+ sfmData::Landmark landmark = landmarksData[i];
225223
226224 // check number of observations
227225 if (landmark.observations .size () <= maxNbObservationsPerLandmark)
@@ -232,8 +230,7 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark)
232230
233231 // compute observation scores
234232
235- std::vector<std::pair<double , IndexT> > observationScores;
236- observationScores.reserve (landmark.observations .size ());
233+ std::vector<std::pair<double , IndexT>> observationScores (landmark.observations .size ());
237234
238235 for (const auto & observationPair : landmark.observations )
239236 {
@@ -254,7 +251,7 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark)
254251
255252 // replace the observations
256253 Observations filteredObservations;
257- for (auto observationScorePair : observationScores)
254+ for (const auto & observationScorePair : observationScores)
258255 {
259256 filteredObservations[observationScorePair.second ] = landmark.observations [observationScorePair.second ];
260257 }
@@ -273,6 +270,11 @@ int aliceVision_main(int argc, char *argv[])
273270 int maxNbObservationsPerLandmark = 5 ;
274271 double radiusScale = 2 ;
275272
273+ // user optional parameters
274+ std::vector<std::string> featuresFolders;
275+ std::vector<std::string> matchesFolders;
276+ std::string describerTypesName = feature::EImageDescriberType_enumToString (feature::EImageDescriberType::SIFT);
277+
276278 po::options_description requiredParams (" Required parameters" );
277279 requiredParams.add_options ()
278280 (" input,i" , po::value<std::string>(&inputSfmFilename)->required (),
@@ -285,7 +287,13 @@ int aliceVision_main(int argc, char *argv[])
285287 (" maxNbObservationsPerLandmark" , po::value<int >(&maxNbObservationsPerLandmark)->default_value (maxNbObservationsPerLandmark),
286288 " Maximum number of allowed observations per landmark." )
287289 (" radiusScale" , po::value<double >(&radiusScale)->default_value (radiusScale),
288- " Scale factor applied to pixel size based radius filter applied to landmarks." );
290+ " Scale factor applied to pixel size based radius filter applied to landmarks." )
291+ (" featuresFolders,f" , po::value<std::vector<std::string>>(&featuresFolders)->multitoken (),
292+ " Path to folder(s) containing the extracted features." )
293+ (" matchesFolders,m" , po::value<std::vector<std::string>>(&matchesFolders)->multitoken (),
294+ " Path to folder(s) in which computed matches are stored." )
295+ (" describerTypes,d" , po::value<std::string>(&describerTypesName)->default_value (describerTypesName),
296+ feature::EImageDescriberType_informations ().c_str ());
289297
290298 CmdLine cmdline (" AliceVision SfM filtering." );
291299 cmdline.add (requiredParams);
@@ -311,18 +319,22 @@ int aliceVision_main(int argc, char *argv[])
311319 }
312320
313321 // filter SfM data
314- ALICEVISION_LOG_INFO ( " Filtering landmarks: started. " );
315- bool success2 = filterLandmarks (sfmData, radiusScale);
316- ALICEVISION_LOG_INFO (" Filtering landmarks: done ." );
317- ALICEVISION_LOG_INFO ( " Filtering observations: started. " );
318- bool success1 = filterObservations (sfmData, maxNbObservationsPerLandmark );
319- ALICEVISION_LOG_INFO ( " Filtering observations: done. " );
320-
321- if (success1 )
322+ if (radiusScale > 0 )
323+ {
324+ ALICEVISION_LOG_INFO (" Filtering landmarks: started ." );
325+ filterLandmarks (sfmData, radiusScale );
326+ ALICEVISION_LOG_INFO ( " Filtering landmarks: done. " );
327+ }
328+
329+ if (maxNbObservationsPerLandmark > 0 )
322330 {
323- sfmDataIO::Save (sfmData, outputSfmFilename, sfmDataIO::ESfMData::ALL);
324- return EXIT_SUCCESS;
331+ ALICEVISION_LOG_INFO (" Filtering observations: started." );
332+ filterObservations (sfmData, maxNbObservationsPerLandmark);
333+ ALICEVISION_LOG_INFO (" Filtering observations: done." );
325334 }
326335
327- return EXIT_FAILURE;
336+
337+ sfmDataIO::Save (sfmData, outputSfmFilename, sfmDataIO::ESfMData::ALL);
338+ return EXIT_SUCCESS;
339+
328340}
0 commit comments