34#include "DGtal/base/Common.h"
35#include "DGtal/topology/VoxelComplex.h"
36#include "DGtal/topology/VoxelComplexFunctions.h"
37#include "DGtal/geometry/volumes/distance/DistanceTransformation.h"
38#include "DGtal/geometry/volumes/distance/ExactPredicateLpSeparableMetric.h"
89template<
typename TComplex,
90 typename TDistanceTransform =
91 DistanceTransformation<Z3i::Space, Z3i::DigitalSet, ExactPredicateLpSeparableMetric<Z3i::Space, 3>> >
94 const std::string & skel_type_str,
95 const std::string & skel_select_type_str,
96 const std::string & tables_folder,
97 const int & persistence = 0,
98 const TDistanceTransform * distance_transform =
nullptr,
99 const bool profile =
false,
100 const bool verbose =
false)
105 trace.
info() <<
"skel_type_str: " << skel_type_str << std::endl;
106 trace.
info() <<
"skel_select_type_str: " << skel_select_type_str << std::endl;
107 if(distance_transform) {
108 trace.
info() <<
" -- provided distance_transform." << std::endl;
110 trace.
info() <<
"persistence: " << persistence << std::endl;
111 trace.
info() <<
"profile: " << profile << std::endl;
112 trace.
info() <<
"verbose: " << verbose << std::endl;
113 trace.
info() <<
"----------" << std::endl;
118 const bool skel_type_str_is_valid =
119 skel_type_str ==
"ultimate" ||
120 skel_type_str ==
"end" ||
121 skel_type_str ==
"isthmus" ||
122 skel_type_str ==
"1isthmus" ||
123 skel_type_str ==
"isthmus1";
124 if(!skel_type_str_is_valid) {
125 throw std::runtime_error(
"skel_type_str is not valid: \"" + skel_type_str +
"\"");
128 const bool skel_select_type_str_is_valid =
129 skel_select_type_str ==
"first" ||
130 skel_select_type_str ==
"random" ||
131 skel_select_type_str ==
"dmax";
132 if(!skel_select_type_str_is_valid) {
133 throw std::runtime_error(
"skel_select_type_str is not valid: \"" + skel_select_type_str +
"\"");
146 using Complex = TComplex;
147 using ComplexCell =
typename Complex::Cell;
148 using ComplexClique =
typename Complex::Clique;
152 boost::dynamic_bitset<> isthmus_table;
153 auto &sk = skel_type_str;
154 if(sk ==
"isthmus") {
155 const std::string tableIsthmus = tables_folder +
"/isthmusicity_table26_6.zlib";
157 }
else if(sk ==
"isthmus1" || sk ==
"1ishtmus") {
158 const std::string tableOneIsthmus = tables_folder +
"/isthmusicityOne_table26_6.zlib";
167 *DGtal::functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
168 std::function<bool(
const Complex&,
const ComplexCell&)> Skel;
169 if(sk ==
"ultimate") {
170 Skel = DGtal::functions::skelUltimate<Complex>;
171 }
else if(sk ==
"end") {
172 Skel = DGtal::functions::skelEnd<Complex>;
175 }
else if(sk ==
"isthmus1" || sk ==
"1ishtmus") {
176 Skel = [&isthmus_table, &pointMap](
const Complex& fc,
177 const ComplexCell& c) {
180 }
else if(sk ==
"isthmus") {
181 Skel = [&isthmus_table, &pointMap](
const Complex& fc,
182 const ComplexCell& c) {
186 throw std::runtime_error(
"Invalid skel string");
190 std::function<std::pair<typename Complex::Cell, typename Complex::Data>(
191 const ComplexClique&)>
195 auto start = std::chrono::system_clock::now();
198 using DT = TDistanceTransform;
199 using DTDigitalSet =
typename DT::PointPredicate;
200 using DTDigitalSetDomain =
typename DTDigitalSet::Domain;
201 using Metric =
typename DT::SeparableMetric;
203 auto &sel = skel_select_type_str;
204 const bool compute_distance_transform = !distance_transform && sel ==
"dmax";
205 DTDigitalSetDomain vc_domain = compute_distance_transform ?
206 DTDigitalSetDomain(vc.space().lowerBound(), vc.space().upperBound()) :
210 DTDigitalSet image_set = DTDigitalSet(vc_domain);
211 if(compute_distance_transform) {
212 vc.dumpVoxels(image_set);
215 DT dist_map(vc_domain, image_set, l3);
216 if(compute_distance_transform) {
217 distance_transform = &dist_map;
220 if(sel ==
"random") {
221 Select = DGtal::functions::selectRandom<Complex>;
222 }
else if(sel ==
"first") {
223 Select = DGtal::functions::selectFirst<Complex>;
224 }
else if(sel ==
"dmax") {
225 Select = [&distance_transform](
const ComplexClique& clique) {
226 return selectMaxValue<TDistanceTransform, Complex>(*distance_transform, clique);
229 throw std::runtime_error(
"Invalid skel select type");
233 Complex vc_new(vc.space());
234 if(persistence == 0) {
235 vc_new = DGtal::functions::asymetricThinningScheme<Complex>(vc, Select, Skel, verbose);
237 vc_new = DGtal::functions::persistenceAsymetricThinningScheme<Complex>(vc, Select, Skel,
238 persistence, verbose);
242 auto end = std::chrono::system_clock::now();
243 auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(end - start);
245 std::cout <<
"Time elapsed: " << elapsed.count() << std::endl;
Aim: This class is a model of CCellularGridSpaceND. It represents the cubical grid as a cell complex,...
static Self diagonal(Component val=1)
static Self zero
Static const for zero PointVector.
void beginBlock(const std::string &keyword="")
KhalimskySpaceND< 3, Integer > KSpace
bool skelWithTable(const boost::dynamic_bitset<> &table, const std::unordered_map< typename TComplex::Point, unsigned int > &pointToMaskMap, const TComplex &vc, const typename TComplex::Cell &cell)
DGtal::CountedPtr< boost::dynamic_bitset<> > loadTable(const std::string &input_filename, const unsigned int known_size, const bool compressed=true)
TComplex thinningVoxelComplex(TComplex &vc, const std::string &skel_type_str, const std::string &skel_select_type_str, const std::string &tables_folder, const int &persistence=0, const TDistanceTransform *distance_transform=nullptr, const bool profile=false, const bool verbose=false)
DGtal is the top-level namespace which contains all DGtal functions and types.