diff --git a/CMakeLists.txt b/CMakeLists.txt index a844f5ec..6064f23e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ cmake_minimum_required (VERSION 3.20) PROJECT(DGtalTools) +cmake_minimum_required (VERSION 3.11) cmake_policy(SET CMP0057 NEW) # the new interpretation of IN_LIST is by default not set (at least until 3.21.1). LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") diff --git a/volumetric/CMakeLists.txt b/volumetric/CMakeLists.txt index 8548bd36..6387fb8f 100644 --- a/volumetric/CMakeLists.txt +++ b/volumetric/CMakeLists.txt @@ -16,6 +16,7 @@ SET(DGTAL_TOOLS_SRC volFillInterior volInfo volMask + volEuclideanDT ) diff --git a/volumetric/volEuclideanDT.cpp b/volumetric/volEuclideanDT.cpp new file mode 100644 index 00000000..1a7b9cea --- /dev/null +++ b/volumetric/volEuclideanDT.cpp @@ -0,0 +1,203 @@ +/** + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + **/ + +/** + * @file volEuclideanDT.cpp + * @author David Coeurjolly (\c david.coeurjolly@liris.cnrs.fr ) + * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France + * + * @date 2021/01/25 + * + * + * This file is part of the DGtal library. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "DGtal/geometry/volumes/distance/PowerMap.h" +#include "DGtal/geometry/volumes/distance/ReducedMedialAxis.h" +#include "DGtal/geometry/volumes/distance/ExactPredicateLpPowerSeparableMetric.h" + +#include + + +using namespace std; +using namespace DGtal; +using namespace Z3i; + + +/** + @page volEuclideanDT volEuclideanDT + + @brief Tool to compute and output Euclidean distance related quantitites (the distance transform, the Voronoi map, the RDMA...). + + + @b Usage: ./volumetric/volEuclideanDT [OPTIONS] 1 [2] + + + @b Allowed @b options @b are : + @code + + @endcode + + @b Example: + + @see + @ref volEuclideanDT.cpp + + */ + +template +struct functorCast{ + + unsigned char operator()(const T &v) {return v%256;} +}; + + +/** + * Missing parameter error message. + * + * @param param + */ +void missingParam ( std::string param ) +{ + trace.error() <<" Parameter: "< --o "); + + std::string inputFileName; + app.add_option("-i,--input,1", inputFileName, "Input vol file." )->required()->check(CLI::ExistingFile); + std::string outputFileName; + app.add_option("-o,--output,2", outputFileName, "Output filename.",true); + + std::string mode="edt"; + app.add_option("-m,--mode", mode, "Export mode for the distance: {edt (remappred distances to the [0:255] range),sedt (exact square of distances as longvol),voronoi (Voronoi map using hash value per cell), rdma (centre of maximal balls)} (default:edt)", true)-> check(CLI::IsMember({"edt", "sedt", "voronoi", "rdma"})); + + app.get_formatter()->column_width(40); + CLI11_PARSE(app, argc, argv); + + + trace.beginBlock("Loading file"); + typedef ImageContainerBySTLVector Image; + Image image = VolReader< Image >::importVol ( inputFileName ); + trace.info()< Predicate; + Predicate aPredicate(image,0); + DistanceTransformation dt(image.domain(), aPredicate, Z3i::l2Metric); + trace.info()<::max(); + for(auto v: dt.constRange()) + { + valMax=std::max(valMax,v); + valMin=std::min(valMin,v); + } + + if (mode == "edt") + { + Image output(image.domain()); + for(auto &voxel: image.domain()) + { + auto val = dt(voxel); + unsigned char valC = static_cast( 255*(val+valMin)/(valMax-valMin) ); + output.setValue(voxel, valC); + } + VolWriter::exportVol(outputFileName, output); + } + else + if (mode == "sedt") + { + ImageContainerBySTLVector output(image.domain()); + for(auto &voxel: image.domain()) + { + auto val = l2Metric.rawDistance(voxel, dt.getVoronoiVector(voxel)); + output.setValue(voxel, val); + } + size_t lastindex = outputFileName.find_last_of("."); + std::string rawname = outputFileName.substr(0, lastindex); + LongvolWriter< ImageContainerBySTLVector>::exportLongvol(rawname+".longvol", output); + } + else + if (mode == "voronoi") + { + auto myhash=[](const Z3i::Point &p){return (((p[0])*43 + p[1]*1777)*123 + p[2]) % 256;}; + Image output(image.domain()); + for(auto &voxel: image.domain()) + { + auto site = dt.getVoronoiVector(voxel); + unsigned char v=0; + if (site == voxel) + v = 0; + else + v = myhash(site); + output.setValue(voxel, v); + } + VolWriter::exportVol(outputFileName, output); + } + else + if (mode == "rdma") + { + typedef ImageContainerBySTLVector ImageLong; + ImageLong rawDT(image.domain()); + for(auto &voxel: image.domain()) + { + auto val = l2Metric.rawDistance(voxel, dt.getVoronoiVector(voxel)); + rawDT.setValue(voxel, val); + } + PowerMap powermap(rawDT.domain(), rawDT, l2PowerMetric); + ReducedMedialAxis >::Type rdma = ReducedMedialAxis< PowerMap >::getReducedMedialAxisFromPowerMap(powermap); + auto cpt2=0; + for(auto v: dt.constRange()) + if (v!=0) cpt2++; + auto cpt=0; + + Image out(image.domain()); + std::vector> ma; + for(auto &voxel: rdma.domain()) + { + out.setValue(voxel, rdma(voxel) % 256); + if (rdma(voxel) != 0) + ma.push_back( std::pair(voxel ,std::sqrt(rdma(voxel))) ); + } + VolWriter::exportVol(outputFileName, out); + } + return 0; +}