99// Standard libs
1010#include < iostream>
1111#include < numeric>
12+ #include < string>
13+
14+ #include < aliceVision/utils/convert.hpp>
1215
1316// AliceVision image library
1417#include < aliceVision/image/Image.hpp>
@@ -236,10 +239,6 @@ void sphereDetection(const sfmData::SfMData& sfmData, Ort::Session& session, fs:
236239 }
237240 }
238241
239-
240-
241-
242-
243242 // Main tree
244243 bpt::ptree fileTree;
245244 fillShapeTree (fileTree, spheresTree);
@@ -248,26 +247,55 @@ void sphereDetection(const sfmData::SfMData& sfmData, Ort::Session& session, fs:
248247 bpt::write_json (outputPath.string (), fileTree);
249248}
250249
251- void writeManualSphereJSON (const sfmData::SfMData& sfmData, const std::array<float , 3 >& sphereParam, fs::path outputPath)
250+ bool writeManualSphereJSON (const sfmData::SfMData& sfmData,
251+ const std::vector<std::string>& x,
252+ const std::vector<std::string>& y,
253+ const std::vector<std::string>& radius,
254+ fs::path outputPath,
255+ bool fillMissingSpheres)
252256{
257+ auto xValues = aliceVision::utils::dictStringToStringMap (x);
258+ auto yValues = aliceVision::utils::dictStringToStringMap (y);
259+ auto radiusValues = aliceVision::utils::dictStringToStringMap (radius);
260+
253261 // Spheres tree
254262 bpt::ptree spheresTree;
255263
256264 for (auto & viewID : sfmData.getViews ())
257265 {
258- ALICEVISION_LOG_DEBUG (" View Id: " << viewID);
259-
266+ ALICEVISION_LOG_DEBUG (" View ID: " << viewID);
260267 const std::string sphereName = std::to_string (viewID.second ->getViewId ());
261268
269+ std::vector<float > sphereParams;
270+ auto pos = xValues.find (sphereName);
271+ if (pos == xValues.end ())
272+ {
273+ ALICEVISION_LOG_INFO (" Sphere shape for view ID " << sphereName << " not found." );
274+
275+ if (fillMissingSpheres)
276+ {
277+ ALICEVISION_LOG_INFO (" Using sphere position from view ID " << xValues.rbegin ()->first << " ." );
278+ sphereParams = {std::stof (xValues.rbegin ()->second ), std::stof (yValues.rbegin ()->second ), std::stof (radiusValues.rbegin ()->second )};
279+ }
280+ }
281+ else
282+ {
283+ ALICEVISION_LOG_DEBUG (" Sphere shape for view ID " << sphereName << " found." );
284+ sphereParams = {std::stof (xValues.at (sphereName)), std::stof (yValues.at (sphereName)), std::stof (radiusValues.at (sphereName))};
285+ }
286+
262287 // Create an unnamed node containing the sphere
263- bpt::ptree sphereNode;
264- sphereNode.put (" center.x" , sphereParam[0 ]);
265- sphereNode.put (" center.y" , sphereParam[1 ]);
266- sphereNode.put (" radius" , sphereParam[2 ]);
267- sphereNode.put (" type" , " matte" );
268-
269- // Add sphere node to spheres tree
270- spheresTree.add_child (sphereName, sphereNode);
288+ if (!sphereParams.empty ())
289+ {
290+ bpt::ptree sphereNode;
291+ sphereNode.put (" center.x" , sphereParams[0 ]);
292+ sphereNode.put (" center.y" , sphereParams[1 ]);
293+ sphereNode.put (" radius" , sphereParams[2 ]);
294+ sphereNode.put (" type" , " matte" );
295+
296+ // Add sphere node to spheres tree
297+ spheresTree.add_child (sphereName, sphereNode);
298+ }
271299 }
272300
273301 // Shapes tree
@@ -296,6 +324,74 @@ void writeManualSphereJSON(const sfmData::SfMData& sfmData, const std::array<flo
296324
297325 // Write JSON
298326 bpt::write_json (outputPath.string (), fileTree);
327+
328+ return true ;
329+ }
330+
331+ bool writeManualSphereJSON (const sfmData::SfMData& sfmData, const std::string& sphereFile, const std::string& outputPath, bool fillMissingSpheres)
332+ {
333+ if (!fillMissingSpheres)
334+ {
335+ // Copy the file as is if since there is no need to check on missing spheres
336+ fs::copy_file (sphereFile, outputPath);
337+ return true ;
338+ }
339+
340+ // Main tree
341+ bpt::ptree fileTree;
342+
343+ // Read the json file and initialize the tree
344+ bpt::read_json (sphereFile, fileTree);
345+
346+ // Spheres tree
347+ bpt::ptree spheresTree;
348+
349+ // Initialize spheres tree
350+ const auto shapesTreeOpt = fileTree.get_child_optional (" shapes" );
351+ if (shapesTreeOpt && !shapesTreeOpt->empty ())
352+ {
353+ const auto & firstShapeTree = shapesTreeOpt->begin ()->second ;
354+ spheresTree = firstShapeTree.get_child (" observations" );
355+ }
356+ else
357+ {
358+ ALICEVISION_THROW_ERROR (" Cannot find sphere detection data in '" << sphereFile << " '." );
359+ }
360+
361+ std::string lastSphereViewID = spheresTree.rbegin ()->first ;
362+ std::vector<float > sphereParams = {spheresTree.rbegin ()->second .get (" center.x" , 0 .0f ),
363+ spheresTree.rbegin ()->second .get (" center.y" , 0 .0f ),
364+ spheresTree.rbegin ()->second .get (" radius" , 0 .0f )};
365+
366+ ALICEVISION_LOG_INFO (" Got last known sphere position: " << lastSphereViewID);
367+
368+ for (auto & viewID : sfmData.getViews ())
369+ {
370+ ALICEVISION_LOG_DEBUG (" View ID: " << viewID);
371+ const std::string sphereName = std::to_string (viewID.second ->getViewId ());
372+
373+ auto sphereExists = (spheresTree.get_child_optional (sphereName)).is_initialized ();
374+ if (!sphereExists)
375+ {
376+ ALICEVISION_LOG_INFO (" Sphere exists" );
377+ bpt::ptree sphereNode;
378+ sphereNode.put (" center.x" , sphereParams[0 ]);
379+ sphereNode.put (" center.y" , sphereParams[1 ]);
380+ sphereNode.put (" radius" , sphereParams[2 ]);
381+ sphereNode.put (" type" , " matte" );
382+
383+ // Add sphere node to spheres tree
384+ spheresTree.add_child (sphereName, sphereNode);
385+ }
386+ }
387+
388+ fileTree.clear ();
389+ fillShapeTree (fileTree, spheresTree);
390+
391+ // Write JSON
392+ bpt::write_json (outputPath, fileTree);
393+
394+ return true ;
299395}
300396
301397} // namespace sphereDetection
0 commit comments