diff --git a/src/aliceVision/image/io.cpp b/src/aliceVision/image/io.cpp index faecc7466d..5c99b8384d 100644 --- a/src/aliceVision/image/io.cpp +++ b/src/aliceVision/image/io.cpp @@ -1288,15 +1288,15 @@ void writeImageWithFloat(const std::string& path, const Image& image, bool tryLoadMask(Image* mask, const std::vector& masksFolders, - const IndexT viewId, const std::string & srcImage) + const IndexT viewId, const std::string& srcImage, const std::string& fileExtension) { for (const auto & masksFolder_str : masksFolders) { if (!masksFolder_str.empty() && fs::exists(masksFolder_str)) { const auto masksFolder = fs::path(masksFolder_str); - const auto idMaskPath = masksFolder / fs::path(std::to_string(viewId)).replace_extension("png"); - const auto nameMaskPath = masksFolder / fs::path(srcImage).filename().replace_extension("png"); + const auto idMaskPath = masksFolder / fs::path(std::to_string(viewId)).replace_extension(fileExtension); + const auto nameMaskPath = masksFolder / fs::path(srcImage).filename().replace_extension(fileExtension); if (fs::exists(idMaskPath)) { diff --git a/src/aliceVision/image/io.hpp b/src/aliceVision/image/io.hpp index 4e3a0077ca..cbf73647c5 100644 --- a/src/aliceVision/image/io.hpp +++ b/src/aliceVision/image/io.hpp @@ -506,7 +506,7 @@ struct ColorTypeInfo }; bool tryLoadMask(Image* mask, const std::vector& masksFolders, - const IndexT viewId, const std::string & srcImage); + const IndexT viewId, const std::string& srcImage, const std::string& fileExtension); /** * Returns the value of ALICEVISION_ROOT environmental variable, or empty string if it is not diff --git a/src/software/pipeline/main_imageSegmentation.cpp b/src/software/pipeline/main_imageSegmentation.cpp index 13c1c16aa6..764db64e1e 100644 --- a/src/software/pipeline/main_imageSegmentation.cpp +++ b/src/software/pipeline/main_imageSegmentation.cpp @@ -34,7 +34,7 @@ // 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 +#define ALICEVISION_SOFTWARE_VERSION_MINOR 1 using namespace aliceVision; @@ -65,14 +65,18 @@ void imageToPlanes(std::vector & output, const image::Image & mask, const image::Image & labels, const std::set & validClasses) +void labelsToMask(image::Image & mask, const image::Image & labels, const std::set & validClasses, + const bool & maskInvert) { for (int i = 0; i < mask.Height(); i++) { for (int j = 0; j < mask.Width(); j++) { IndexT label = labels(i, j); - mask(i, j) = (validClasses.find(label) != validClasses.end()) ? 255 : 0; + if (maskInvert) + mask(i, j) = (validClasses.find(label) != validClasses.end()) ? 0 : 255; + else + mask(i, j) = (validClasses.find(label) != validClasses.end()) ? 255 : 0; } } } @@ -83,20 +87,23 @@ int aliceVision_main(int argc, char** argv) std::string outputPath; std::string modelWeightsPath; std::vector validClasses; + bool maskInvert = false; int rangeStart = -1; int rangeSize = 1; // Description of mandatory parameters po::options_description requiredParams("Required parameters"); requiredParams.add_options() - ("input,i", po::value(&sfmDataFilepath)->required(), "Input sfmData.") + ("input,i", po::value(&sfmDataFilepath)->required(), "Input SfMData.") ("modelPath,m", po::value(&modelWeightsPath)->required(), "Input Model weights file.") - ("output,o", po::value(&outputPath)->required(), "output folder."); + ("output,o", po::value(&outputPath)->required(), "Output folder."); po::options_description optionalParams("Optional parameters"); optionalParams.add_options() ("validClasses,c", po::value>(&validClasses)->multitoken(), - "Names of classes which are to be considered") + "Names of classes which are to be considered.") + ("maskInvert", po::value(&maskInvert)->default_value(maskInvert), + "Invert mask values. If selected, the pixels corresponding to the mask will be set to 0.0 instead of 1.0.") ("rangeStart", po::value(&rangeStart)->default_value(rangeStart), "Range start for processing views (ordered by image filepath). Set to -1 to process all images.") ("rangeSize", po::value(&rangeSize)->default_value(rangeSize), @@ -231,7 +238,7 @@ int aliceVision_main(int argc, char** argv) image::Image mask(labels.Width(), labels.Height()); - labelsToMask(mask, labels, validClassesIndices); + labelsToMask(mask, labels, validClassesIndices, maskInvert); if (pixelRatio != 1.0) { @@ -247,7 +254,7 @@ int aliceVision_main(int argc, char** argv) mask.swap(resizedMask); } - //Store image + // Store image std::stringstream ss; ss << outputPath << "/" << view->getViewId() << ".exr"; image::writeImage(ss.str(), mask, image::ImageWriteOptions()); diff --git a/src/software/pipeline/main_meshMasking.cpp b/src/software/pipeline/main_meshMasking.cpp index 1ce6b92aaa..e9f0b42f24 100644 --- a/src/software/pipeline/main_meshMasking.cpp +++ b/src/software/pipeline/main_meshMasking.cpp @@ -24,7 +24,7 @@ // 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 +#define ALICEVISION_SOFTWARE_VERSION_MINOR 1 using namespace aliceVision; @@ -38,10 +38,12 @@ namespace fs = boost::filesystem; */ struct MaskCache { - MaskCache(const mvsUtils::MultiViewParams& mp, const std::vector& masksFolders, bool undistortMasks, int maxSize = 16) + MaskCache(const mvsUtils::MultiViewParams& mp, const std::vector& masksFolders, bool undistortMasks, + const std::string maskExtension, int maxSize = 16) : _mp(mp) , _masksFolders(masksFolders) , _undistortMasks(undistortMasks) + , _maskExtension(maskExtension) , _maxSize(maxSize) { } @@ -68,7 +70,7 @@ struct MaskCache item = &_cache.back(); const IndexT viewId = _mp.getViewId(camId); auto * const mask = item->mask.get(); - const bool loaded = tryLoadMask(mask, _masksFolders, viewId, _mp.getImagePath(camId)); + const bool loaded = tryLoadMask(mask, _masksFolders, viewId, _mp.getImagePath(camId), _maskExtension); if (loaded) { if (_undistortMasks) @@ -147,6 +149,7 @@ struct MaskCache mvsUtils::MultiViewParams _mp; std::vector _masksFolders; bool _undistortMasks; + std::string _maskExtension; int _maxSize; std::vector _cache; }; @@ -347,6 +350,7 @@ void meshMasking( const mvsUtils::MultiViewParams & mp, mesh::Mesh & inputMesh, const std::vector & masksFolders, + const std::string & maskExtension, const std::string & outputMeshPath, const int threshold, const bool invert, @@ -355,7 +359,7 @@ void meshMasking( const bool usePointsVisibilities ) { - MaskCache maskCache(mp, masksFolders, undistortMasks); + MaskCache maskCache(mp, masksFolders, undistortMasks, maskExtension); // compute visibility for every vertex // also update inputMesh.pointsVisibilities according to the masks @@ -513,6 +517,7 @@ int main(int argc, char **argv) bool smoothBoundary = false; bool undistortMasks = false; bool usePointsVisibilities = false; + std::string maskExtension = "png"; po::options_description requiredParams("Required parameters"); requiredParams.add_options() @@ -539,6 +544,8 @@ int main(int argc, char **argv) "Undistort the masks with the same parameters as the matching image. Use it if the masks are drawn on the original images.") ("usePointsVisibilities", po::value(&usePointsVisibilities)->default_value(usePointsVisibilities), "Use the points visibilities from the meshing to filter triangles. Example: when they are occluded, back-face, etc.") + ("maskExtension", po::value(&maskExtension)->default_value(maskExtension), + "File extension for the masks to use.") ; CmdLine cmdline("AliceVision meshMasking"); @@ -613,7 +620,7 @@ int main(int argc, char **argv) } ALICEVISION_LOG_INFO("Mask mesh"); - meshMasking(mp, inputMesh, masksFolders, outputMeshPath, threshold, invert, smoothBoundary, undistortMasks, usePointsVisibilities); + meshMasking(mp, inputMesh, masksFolders, maskExtension, outputMeshPath, threshold, invert, smoothBoundary, undistortMasks, usePointsVisibilities); ALICEVISION_LOG_INFO("Task done in (s): " + std::to_string(timer.elapsed())); return EXIT_SUCCESS; } diff --git a/src/software/pipeline/main_prepareDenseScene.cpp b/src/software/pipeline/main_prepareDenseScene.cpp index 89cc4e7cee..996134a605 100644 --- a/src/software/pipeline/main_prepareDenseScene.cpp +++ b/src/software/pipeline/main_prepareDenseScene.cpp @@ -29,7 +29,7 @@ // These constants define the current software version. // They must be updated when the command line is changed. #define ALICEVISION_SOFTWARE_VERSION_MAJOR 2 -#define ALICEVISION_SOFTWARE_VERSION_MINOR 0 +#define ALICEVISION_SOFTWARE_VERSION_MINOR 1 using namespace aliceVision; using namespace aliceVision::camera; @@ -79,6 +79,7 @@ void process(const std::string &dstColorImage, const IntrinsicBase* cam, const o bool prepareDenseScene(const SfMData& sfmData, const std::vector& imagesFolders, const std::vector& masksFolders, + const std::string& maskExtension, int beginIndex, int endIndex, const std::string& outFolder, @@ -246,7 +247,7 @@ bool prepareDenseScene(const SfMData& sfmData, } image::Image mask; - if(tryLoadMask(&mask, masksFolders, viewId, srcImage)) + if(tryLoadMask(&mask, masksFolders, viewId, srcImage, maskExtension)) { process>(dstColorImage, cam, metadata, srcImage, evCorrection, exposureCompensation, [&mask] (Image & image) { @@ -286,6 +287,7 @@ int aliceVision_main(int argc, char *argv[]) std::string outImageFileTypeName = image::EImageFileType_enumToString(image::EImageFileType::EXR); std::vector imagesFolders; std::vector masksFolders; + std::string maskExtension = "png"; int rangeStart = -1; int rangeSize = 1; bool saveMetadata = true; @@ -307,6 +309,8 @@ int aliceVision_main(int argc, char *argv[]) ("masksFolders", po::value>(&masksFolders)->multitoken(), "Use masks from specific folder(s).\n" "Filename should be the same or the image uid.") + ("maskExtension", po::value(&maskExtension)->default_value(maskExtension), + "File extension of the masks to use.") ("outputFileType", po::value(&outImageFileTypeName)->default_value(outImageFileTypeName), image::EImageFileType_informations().c_str()) ("saveMetadata", po::value(&saveMetadata)->default_value(saveMetadata), @@ -371,7 +375,7 @@ int aliceVision_main(int argc, char *argv[]) } // export - if(prepareDenseScene(sfmData, imagesFolders, masksFolders, rangeStart, rangeEnd, + if(prepareDenseScene(sfmData, imagesFolders, masksFolders, maskExtension, rangeStart, rangeEnd, outFolder, outputFileType, saveMetadata, saveMatricesTxtFiles, evCorrection)) return EXIT_SUCCESS;