Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions meshroom/aliceVision/TracksShapesInjecting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
__version__ = "1.0"

from meshroom.core import desc
from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL


class TracksShapesInjecting(desc.AVCommandLineNode):
commandLine = "aliceVision_tracksShapesInjecting {allParams}"
size = desc.DynamicNodeSize("input")

category = "Utils"
documentation = """
This node creates tracks from keyable points drawn inside meshroom
"""

inputs = [
desc.File(
name="input",
label="SfMData",
description="Input SfMData file.",
value="",
exposed=True,
),
desc.File(
name="shapesFile",
label="Shapes File",
description="Shapes File used to load shapes from meshroom.",
value="",
exposed=True,
),
desc.BoolParam(
name="markAsSpecial",
label="Is survey",
description="Consider those tracks as 'special' : non removable and very precise.",
value=True,
),
desc.ChoiceParam(
name="verboseLevel",
label="Verbose Level",
description="Verbosity level (fatal, error, warning, info, debug, trace).",
values=VERBOSE_LEVEL,
value="info",
),
]

outputs = [
desc.File(
name="output",
label="Tracks",
description="Path to the output tracks file.",
value="{nodeCacheFolder}/tracksFile.json",
),
]
5 changes: 5 additions & 0 deletions src/aliceVision/feature/imageDescriberCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ std::string EImageDescriberType_informations()
#endif
"* akaze_ocv: OpenCV implementation of A-KAZE describer.\n"
#endif
"* manual: Manually selected points.\n "
"";
}

Expand All @@ -62,6 +63,8 @@ std::string EImageDescriberType_enumToString(EImageDescriberType imageDescriberT
return "akaze_liop";
case EImageDescriberType::AKAZE_MLDB:
return "akaze_mldb";
case EImageDescriberType::MANUAL:
return "manual";

#if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG)
case EImageDescriberType::CCTAG3:
Expand Down Expand Up @@ -113,6 +116,8 @@ EImageDescriberType EImageDescriberType_stringToEnum(const std::string& imageDes
return EImageDescriberType::AKAZE_LIOP;
if (type == "akaze_mldb")
return EImageDescriberType::AKAZE_MLDB;
if (type == "manual")
return EImageDescriberType::MANUAL;

#if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG)
if (type == "cctag3")
Expand Down
5 changes: 4 additions & 1 deletion src/aliceVision/feature/imageDescriberCommon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ enum class EImageDescriberType : unsigned char
,
APRILTAG16H5 = 50
#endif
,
MANUAL
};

/**
Expand Down Expand Up @@ -131,7 +133,8 @@ inline float getStrongSupportCoeff(EImageDescriberType imageDescriberType)
case EImageDescriberType::AKAZE_OCV:
return 0.14f;
#endif // ALICEVISION_HAVE_OPENCV

case EImageDescriberType::MANUAL:
return 1.0f;
case EImageDescriberType::UNKNOWN:
return 1.0f;
case EImageDescriberType::UNINITIALIZED:
Expand Down
2 changes: 2 additions & 0 deletions src/aliceVision/matching/svgVisualization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ std::string describerTypeColor(feature::EImageDescriberType descType)
return "purple";
case feature::EImageDescriberType::AKAZE_MLDB:
return "purple";
case feature::EImageDescriberType::MANUAL:
return "white";
#if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG)
case feature::EImageDescriberType::CCTAG3:
return "blue";
Expand Down
14 changes: 13 additions & 1 deletion src/software/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ if (ALICEVISION_BUILD_SFM)
${Boost_LIBRARIES}
)

# Track builder
# Track Simulating
alicevision_add_software(aliceVision_tracksSimulating
SOURCE main_tracksSimulating.cpp
FOLDER ${FOLDER_SOFTWARE_UTILS}
Expand All @@ -85,6 +85,18 @@ if (ALICEVISION_BUILD_SFM)
Boost::json
)

# Track Shapes injecting
alicevision_add_software(aliceVision_tracksShapesInjecting
SOURCE main_tracksShapesInjecting.cpp
FOLDER ${FOLDER_SOFTWARE_UTILS}
LINKS aliceVision_system
aliceVision_cmdline
aliceVision_sfmData
aliceVision_sfmDataIO
aliceVision_track
Boost::program_options
Boost::json
)

# Track from depthmap
alicevision_add_software(aliceVision_depthmapTracksInjecting
Expand Down
153 changes: 153 additions & 0 deletions src/software/utils/main_tracksShapesInjecting.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// This file is part of the AliceVision project.
// Copyright (c) 2025 AliceVision contributors.
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

#include <aliceVision/cmdline/cmdline.hpp>
#include <aliceVision/system/main.hpp>

#include <aliceVision/sfmDataIO/sfmDataIO.hpp>

#include <aliceVision/track/Track.hpp>
#include <aliceVision/track/trackIO.hpp>
#include <aliceVision/track/TracksMerger.cpp>

#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/json.hpp>

#include <string>
#include <sstream>
#include <random>
#include <fstream>

// These constants define the current software version.
// They must be updated when the command line is changed.
#define ALICEVISION_SOFTWARE_VERSION_MAJOR 1
#define ALICEVISION_SOFTWARE_VERSION_MINOR 0

using namespace aliceVision;

namespace po = boost::program_options;

bool readShapes(const std::string & filename, track::TracksMap & map)
{
std::ifstream shapesFile(filename);
if (shapesFile.is_open() == false)
{
return false;
}

// Parse json
std::stringstream buffer;
buffer << shapesFile.rdbuf();

IndexT count = 0;

try
{
boost::json::value jv = boost::json::parse(buffer.str());

// Iterate through the array
for (const auto & item : jv.as_array())
{
boost::json::object obj = item.as_object();
std::string type = boost::json::value_to<std::string>(obj.at("type"));

boost::to_lower(type);

if (type != "point2d")
{
ALICEVISION_LOG_TRACE("Unknown type " << type);
continue;
}

track::Track & track = map[count];
track.descType = feature::EImageDescriberType::MANUAL;

boost::json::object obs = obj.at("observations").as_object();
for (const auto& [strViewId, value] : obs)
{
IndexT viewId = std::stoul(std::string(strViewId));

boost::json::object coords = value.as_object();
double x = boost::json::value_to<double>(coords.at("x"));
double y = boost::json::value_to<double>(coords.at("y"));

track::TrackItem & item = track.featPerView[viewId];
item.featureId = viewId;
item.scale = 1.0;
item.depth = -1.0;
item.coords.x() = x;
item.coords.y() = y;
}

count++;
}
}
catch (const std::exception & e)
{
std::cout << e.what() << std::endl;
return false;
}

return true;
}

int aliceVision_main(int argc, char** argv)
{
// command-line parameters
std::string outputTracksFileName;
std::string sfmDataFileName;
std::string shapesFilename;
bool markAsSpecial = false;

// clang-format off
po::options_description requiredParams("Required parameters");
requiredParams.add_options()
("input,i", po::value<std::string>(&sfmDataFileName)->required(),
"SfmData used for sanity check.")
("shapesFile", po::value<std::string>(&shapesFilename)->required(),
"Shapes to inject.")
("outputTracksFileName,o", po::value<std::string>(&outputTracksFileName)->required(),
"Output Tracks file.");

po::options_description optionalParams("Optional parameters");
optionalParams.add_options()
("markAsSpecial", po::value<bool>(&markAsSpecial)->default_value(markAsSpecial),
"Consider these tracks as robust, precise measurements.");
// clang-format on

CmdLine cmdline("AliceVision tracksShapesInjecting");
cmdline.add(requiredParams);
cmdline.add(optionalParams);
if (!cmdline.execute(argc, argv))
{
return EXIT_FAILURE;
}

// Load input scene
sfmData::SfMData sfmData;
if (!sfmDataIO::load(sfmData, sfmDataFileName, sfmDataIO::ESfMData::VIEWS))
{
ALICEVISION_LOG_ERROR("The input SfMData file '" << sfmDataFileName << "' cannot be read");
return EXIT_FAILURE;
}

track::TracksMap mapTracks;
if (!readShapes(shapesFilename, mapTracks))
{
ALICEVISION_LOG_ERROR("Can't read shapes to '" << shapesFilename << "'");
return EXIT_FAILURE;
}

if (!saveTracks(mapTracks, outputTracksFileName))
{
ALICEVISION_LOG_ERROR("Can't save tracks to '" << outputTracksFileName << "'");
return EXIT_FAILURE;
}


return EXIT_SUCCESS;
}