Skip to content

Commit

Permalink
Removed boost program_options from all fit-model* example apps
Browse files Browse the repository at this point in the history
This completely removes boost program_options as dependency.
  • Loading branch information
patrikhuber committed Dec 15, 2024
1 parent e9e3a35 commit 4fb916a
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 123 deletions.
10 changes: 3 additions & 7 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
# The examples need a few additional dependencies (e.g. boost filesystem, program_options, and OpenCV highgui):
find_package(OpenCV 4 CONFIG REQUIRED core imgproc imgcodecs)

set(Boost_NO_WARN_NEW_VERSIONS ON) # Supress "New Boost version may have incorrect dependencies or import targets" warning
find_package(Boost 1.71.0 REQUIRED COMPONENTS program_options)

find_package(cxxopts CONFIG REQUIRED)

# Simple model fitting (orthographic camera & shape to landmarks) example:
Expand All @@ -14,13 +10,13 @@ target_compile_options(fit-model-simple PRIVATE "$<$<CXX_COMPILER_ID:MSVC>:/bigo

# Model fitting example that fits orthographic camera, shape, blendshapes, and contours:
add_executable(fit-model fit-model.cpp)
target_link_libraries(fit-model PRIVATE eos opencv_core opencv_imgproc opencv_imgcodecs Boost::program_options)
target_link_libraries(fit-model PRIVATE cxxopts::cxxopts eos opencv_core opencv_imgproc opencv_imgcodecs)
target_link_libraries(fit-model PRIVATE "$<$<CXX_COMPILER_ID:GNU>:-pthread>$<$<CXX_COMPILER_ID:Clang>:-pthreads>")
target_compile_options(fit-model PRIVATE "$<$<CXX_COMPILER_ID:MSVC>:/bigobj>")

# Model fitting example that fits orthographic camera, shape, blendshapes, and contours to multiple images:
add_executable(fit-model-multi fit-model-multi.cpp)
target_link_libraries(fit-model-multi PRIVATE eos opencv_core opencv_imgproc opencv_imgcodecs Boost::program_options)
target_link_libraries(fit-model-multi PRIVATE cxxopts::cxxopts eos opencv_core opencv_imgproc opencv_imgcodecs)
target_link_libraries(fit-model-multi PRIVATE "$<$<CXX_COMPILER_ID:GNU>:-pthread>$<$<CXX_COMPILER_ID:Clang>:-pthreads>")
target_compile_options(fit-model-multi PRIVATE "$<$<CXX_COMPILER_ID:MSVC>:/bigobj>")

Expand All @@ -42,7 +38,7 @@ if(EOS_BUILD_CERES_EXAMPLE)

# Single and multi-image non-linear model fitting with Ceres example:
add_executable(fit-model-ceres fit-model-ceres.cpp)
target_link_libraries(fit-model-ceres PRIVATE eos Ceres::ceres opencv_core opencv_imgproc opencv_imgcodecs Boost::program_options)
target_link_libraries(fit-model-ceres PRIVATE cxxopts::cxxopts eos Ceres::ceres opencv_core opencv_imgproc opencv_imgcodecs)
target_compile_options(fit-model-ceres PRIVATE "$<$<CXX_COMPILER_ID:MSVC>:/bigobj>")
install(TARGETS fit-model-ceres DESTINATION bin)
endif()
70 changes: 38 additions & 32 deletions examples/fit-model-ceres.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"

#include "boost/program_options.hpp"
#include <cxxopts.hpp>

#include <chrono>
#include <iostream>
Expand All @@ -48,15 +48,12 @@

using namespace eos;
using namespace ceres;
namespace po = boost::program_options;
using eos::core::Landmark;
using eos::core::LandmarkCollection;
using cv::Mat;
using Eigen::Vector2f;
using std::cout;
using std::endl;
using std::string;
using std::vector;

// print a vector:
template <typename T>
Expand Down Expand Up @@ -84,42 +81,51 @@ std::ostream& operator<<(std::ostream& out, const std::vector<T>& v)
*/
int main(int argc, char* argv[])
{
using std::vector;
using std::string;
cxxopts::Options options("fit-model-ceres",
"A simple example of fitting a 3D Morphable Model using Ceres Solver.");
// clang-format off
options.add_options()
("h,help", "display the help message")
("m,model", "a Morphable Model, containing a shape and albedo model, stored as cereal BinaryArchive",
cxxopts::value<string>()->default_value("../share/sfm_3448.bin"), "filename")
("b,blendshapes", "file with blendshapes",
cxxopts::value<string>()->default_value("../share/expression_blendshapes_3448.bin"), "filename")
("i,image", "an input image",
cxxopts::value<string>()->default_value("data/image_0010.png"), "filename")
("l,landmarks", "2D landmarks for the image, in ibug .pts format",
cxxopts::value<string>()->default_value("data/image_0010.pts"), "filename")
("p,mapping", "landmark identifier to model vertex number mapping",
cxxopts::value<string>()->default_value("../share/ibug_to_sfm.txt"), "filename")
("c,model-contour", "file with model contour indices",
cxxopts::value<string>()->default_value("../share/sfm_model_contours.json"), "filename")
("o,output", "basename for the output obj file",
cxxopts::value<string>()->default_value("out"), "basename");
// clang-format on

using std::filesystem::path;
path modelfile, imagefile, landmarksfile, mappingsfile, contourfile, blendshapesfile, outputfile;
try
{
po::options_description desc("Allowed options");
// clang-format off
desc.add_options()
("help,h", "display the help message")
("model,m", po::value<path>(&modelfile)->required()->default_value("../share/sfm_3448.bin"),
"a Morphable Model, containing a shape and albedo model, stored as cereal BinaryArchive")
("blendshapes,b", po::value<path>(&blendshapesfile)->required()->default_value("../share/expression_blendshapes_3448.bin"),
"file with blendshapes")
("image,i", po::value<path>(&imagefile)->required()->default_value("data/image_0010.png"),
"an input image")
("landmarks,l", po::value<path>(&landmarksfile)->required()->default_value("data/image_0010.pts"),
"2D landmarks for the image, in ibug .pts format")
("mapping,p", po::value<path>(&mappingsfile)->required()->default_value("../share/ibug_to_sfm.txt"),
"landmark identifier to model vertex number mapping")
("model-contour,c", po::value<path>(&contourfile)->required()->default_value("../share/sfm_model_contours.json"),
"file with model contour indices")
("output,o", po::value<path>(&outputfile)->required()->default_value("out"),
"basename for the output obj file");
// clang-format on
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
if (vm.count("help"))
const auto result = options.parse(argc, argv);
if (result.count("help"))
{
cout << "Usage: fit-model-ceres [options]" << endl;
cout << desc;
std::cout << options.help() << std::endl;
return EXIT_SUCCESS;
}
po::notify(vm);
} catch (const po::error& e)

modelfile = result["model"].as<string>(); // required (with default)
blendshapesfile = result["blendshapes"].as<string>(); // required (with default)
imagefile = result["image"].as<string>(); // required (with default)
landmarksfile = result["landmarks"].as<string>(); // required (with default)
mappingsfile = result["mapping"].as<string>(); // required (with default)
contourfile = result["model-contour"].as<string>(); // required (with default)
outputfile = result["output"].as<string>(); // required (with default)
} catch (const std::exception& e)
{
cout << "Error while parsing command-line arguments: " << e.what() << endl;
cout << "Use --help to display a list of options." << endl;
std::cout << "Error while parsing command-line arguments: " << e.what() << std::endl;
std::cout << "Use --help to display a list of options." << std::endl;
return EXIT_FAILURE;
}

Expand Down
97 changes: 60 additions & 37 deletions examples/fit-model-multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"

#include "boost/program_options.hpp"
#include <cxxopts.hpp>

#include <vector>
#include <iostream>
Expand All @@ -45,14 +45,11 @@
#include <optional>

using namespace eos;
namespace po = boost::program_options;
using eos::core::Landmark;
using eos::core::LandmarkCollection;
using cv::Mat;
using std::cout;
using std::endl;
using std::vector;
using std::string;

/**
* @brief Merges isomaps from a live video with a weighted averaging, based
Expand Down Expand Up @@ -137,56 +134,82 @@ class WeightedIsomapAveraging
*/
int main(int argc, char *argv[])
{
using std::vector;
using std::string;
cxxopts::Options options(
"fit-model-multi",
"A simple example of fitting a 3DMM shape model to 2D landmarks of multiple images.");
// clang-format off
options.add_options()
("h,help", "display the help message")
("m,model", "a Morphable Model stored as cereal BinaryArchive",
cxxopts::value<string>()->default_value("../share/sfm_shape_3448.bin"), "filename")
("i,image", "An input image. Repeat this option to input multiple images.",
cxxopts::value<vector<string>>(), "filename")
("l,landmarks", "2D landmarks for the given images, in ibug .pts format. "
"Repeat this option to provide landmarks for multiple images, and make sure to us the same order as the input images.",
cxxopts::value<vector<string>>(), "filename")
("p,mapping", "landmark identifier to model vertex number mapping",
cxxopts::value<string>()->default_value("../share/ibug_to_sfm.txt"), "filename")
("c,model-contour", "file with model contour indices",
cxxopts::value<string>()->default_value("../share/sfm_model_contours.json"), "filename")
("e,edge-topology", "file with model's precomputed edge topology",
cxxopts::value<string>()->default_value("../share/sfm_3448_edge_topology.json"), "filename")
("b,blendshapes", "file with blendshapes",
cxxopts::value<string>()->default_value("../share/expression_blendshapes_3448.bin"), "filename")
("o,output", "basename for the output rendering and obj files",
cxxopts::value<string>()->default_value("out"), "basename");
// clang-format on

using std::filesystem::path;
path modelfile, mappingsfile, contourfile, edgetopologyfile, blendshapesfile, outputfilebase;
vector<path> imagefiles, landmarksfiles;
try
{
po::options_description desc("Allowed options");
// clang-format off
desc.add_options()
("help,h", "display the help message")
("model,m", po::value<path>(&modelfile)->required()->default_value("../share/sfm_shape_3448.bin"),
"a Morphable Model stored as cereal BinaryArchive")
("image,i", po::value<vector<path>>(&imagefiles)->multitoken(),
"an input image")
("landmarks,l", po::value<vector<path>>(&landmarksfiles)->multitoken(),
"2D landmarks for the image, in ibug .pts format")
("mapping,p", po::value<path>(&mappingsfile)->required()->default_value("../share/ibug_to_sfm.txt"),
"landmark identifier to model vertex number mapping")
("model-contour,c", po::value<path>(&contourfile)->required()->default_value("../share/model_contours.json"),
"file with model contour indices")
("edge-topology,e", po::value<path>(&edgetopologyfile)->required()->default_value("../share/sfm_3448_edge_topology.json"),
"file with model's precomputed edge topology")
("blendshapes,b", po::value<path>(&blendshapesfile)->required()->default_value("../share/expression_blendshapes_3448.bin"),
"file with blendshapes")
("output,o", po::value<path>(&outputfilebase)->required()->default_value("out"),
"basename for the output rendering and obj files");
// clang-format on
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
if (vm.count("help"))
const auto result = options.parse(argc, argv);
if (result.count("help"))
{
cout << "Usage: fit-model-multi [options]" << endl;
cout << desc;
std::cout << options.help() << std::endl;
return EXIT_SUCCESS;
}
po::notify(vm);
} catch (const po::error& e)

modelfile = result["model"].as<string>(); // required (with default)
{
const auto imagefiles_str =
result["image"].as<vector<string>>(); // required
for (const auto& imagefile : imagefiles_str)
{
imagefiles.push_back(imagefile);
}
}
{
const auto landmarksfiles_str =
result["landmarks"].as<vector<string>>(); // required
for (const auto& landmarksfile : landmarksfiles_str)
{
landmarksfiles.push_back(landmarksfile);
}
}
mappingsfile = result["mapping"].as<string>(); // required (with default)
contourfile = result["model-contour"].as<string>(); // required (with default)
edgetopologyfile = result["edge-topology"].as<string>(); // required (with default)
blendshapesfile = result["blendshapes"].as<string>(); // required (with default)
outputfilebase = result["output"].as<string>(); // required (with default)
} catch (const std::exception& e)
{
cout << "Error while parsing command-line arguments: " << e.what() << endl;
cout << "Use --help to display a list of options." << endl;
std::cout << "Error while parsing command-line arguments: " << e.what() << std::endl;
std::cout << "Use --help to display a list of options." << std::endl;
return EXIT_FAILURE;
}

if (landmarksfiles.size() != imagefiles.size()) {
cout << "Number of landmarks files not equal to number of images given: " << landmarksfiles.size()
<< "!=" << imagefiles.size() << endl;
cout << "Number of landmarks files not equal to number of images given. Image files: "
<< imagefiles.size() << ", landmark files: " << landmarksfiles.size() << endl;
return EXIT_FAILURE;
}

if (landmarksfiles.empty()) {
cout << "Please give at least 1 image and landmark file." << endl;
cout << "Please input at least 1 image and landmark file." << endl;
return EXIT_FAILURE;
}
// Load the image, landmarks, LandmarkMapper and the Morphable Model:
Expand Down
23 changes: 11 additions & 12 deletions examples/fit-model-simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ using Eigen::Vector4f;
using cv::Mat;
using std::cout;
using std::endl;
using std::string;
using std::vector;

/**
Expand All @@ -63,26 +62,26 @@ using std::vector;
*/
int main(int argc, char* argv[])
{
using std::string;
cxxopts::Options options("fit-model-simple",
"A simple example of fitting a 3DMM shape model to 2D landmarks.");
// clang-format off
options.add_options()
("h,help", "display the help message")
("m,model", "a Morphable Model stored as cereal BinaryArchive",
cxxopts::value<std::string>()->default_value("../share/sfm_shape_3448.bin"), "filename")
cxxopts::value<string>()->default_value("../share/sfm_shape_3448.bin"), "filename")
("i,image", "an input image",
cxxopts::value<std::string>()->default_value("data/image_0010.png"), "filename")
cxxopts::value<string>()->default_value("data/image_0010.png"), "filename")
("l,landmarks", "2D landmarks for the image, in ibug .pts format",
cxxopts::value<std::string>()->default_value("data/image_0010.pts"), "filename")
cxxopts::value<string>()->default_value("data/image_0010.pts"), "filename")
("p,mapping", "landmark identifier to model vertex number mapping",
cxxopts::value<std::string>()->default_value("../share/ibug_to_sfm.txt"), "filename")
cxxopts::value<string>()->default_value("../share/ibug_to_sfm.txt"), "filename")
("o,output", "basename for the output rendering and obj files",
cxxopts::value<std::string>()->default_value("out"), "basename");
cxxopts::value<string>()->default_value("out"), "basename");
// clang-format on

using std::filesystem::path;
path modelfile, imagefile, landmarksfile, mappingsfile, outputbasename;

try
{
const auto result = options.parse(argc, argv);
Expand All @@ -92,11 +91,11 @@ int main(int argc, char* argv[])
return EXIT_SUCCESS;
}

modelfile = result["model"].as<std::string>(); // required (with default)
imagefile = result["image"].as<std::string>(); // required (with default)
landmarksfile = result["landmarks"].as<std::string>(); // required (with default)
mappingsfile = result["mapping"].as<std::string>(); // required (with default)
outputbasename = result["output"].as<std::string>(); // required (with default)
modelfile = result["model"].as<string>(); // required (with default)
imagefile = result["image"].as<string>(); // required (with default)
landmarksfile = result["landmarks"].as<string>(); // required (with default)
mappingsfile = result["mapping"].as<string>(); // required (with default)
outputbasename = result["output"].as<string>(); // required (with default)
} catch (const std::exception& e)
{
std::cout << "Error while parsing command-line arguments: " << e.what() << std::endl;
Expand Down
Loading

0 comments on commit 4fb916a

Please sign in to comment.