DGtal  1.5.beta
testVoxelComplex.cpp File Reference
#include "DGtal/base/SetFunctions.h"
#include "DGtal/helpers/StdDefs.h"
#include "DGtal/topology/CubicalComplexFunctions.h"
#include "DGtal/topology/CubicalComplex.h"
#include "DGtal/topology/KhalimskyCellHashFunctions.h"
#include "DGtal/topology/VoxelComplex.h"
#include "DGtal/topology/VoxelComplexFunctions.h"
#include "DGtalCatch.h"
#include <iostream>
#include <unordered_map>
#include "DGtal/geometry/volumes/distance/DistanceTransformation.h"
#include "DGtal/geometry/volumes/distance/ExactPredicateLpSeparableMetric.h"
#include "DGtal/geometry/volumes/distance/VoronoiMap.h"
#include "DGtal/images/SimpleThresholdForegroundPredicate.h"
#include "DGtal/kernel/BasicPointPredicates.h"
#include "DGtal/topology/NeighborhoodConfigurations.h"
#include "DGtal/topology/tables/NeighborhoodTables.h"
Include dependency graph for testVoxelComplex.cpp:

Go to the source code of this file.

Functions

 TEST_CASE_METHOD (Fixture_complex_diamond, "insertVoxel", "[insert][close]")
 
 TEST_CASE_METHOD (Fixture_complex_diamond, "Faces of voxel", "[neighborhood][faces]")
 
 TEST_CASE_METHOD (Fixture_complex_diamond, "Neighbors from Object and KSpace", "[neighborhood]")
 
 TEST_CASE_METHOD (Fixture_complex_diamond, "Test Simplicity", "[simplicity]")
 
 TEST_CASE_METHOD (Fixture_complex_diamond, "Test table wrappers", "[table][simple]")
 
 TEST_CASE_METHOD (Fixture_complex_diamond, "Cliques Masks K_2", "[clique]")
 
 TEST_CASE_METHOD (Fixture_complex_diamond, "Cliques Masks K_1", "[clique]")
 
 TEST_CASE_METHOD (Fixture_complex_diamond, "Cliques Masks K_0", "[clique]")
 
 TEST_CASE_METHOD (Fixture_complex_diamond, "Get All Critical Cliques of diamond", "[critical][clique]")
 
 TEST_CASE_METHOD (Fixture_complex_fig4, "Get All Critical Cliques of fig4", "[critical][clique]")
 
 TEST_CASE_METHOD (Fixture_complex_fig4, "zeroSurface and oneSurface", "[isSurface][function]")
 
 TEST_CASE_METHOD (Fixture_isthmus, "Thin disconnected complex", "[isthmus][thin][function]")
 
 TEST_CASE_METHOD (Fixture_isthmus, "Check isthmus", "[isthmus][function]")
 
 TEST_CASE_METHOD (Fixture_isthmus, "Thin complex", "[isthmus][thin][function]")
 
 TEST_CASE_METHOD (Fixture_isthmus, "Persistence thin", "[persistence][isthmus][thin][function]")
 
 TEST_CASE_METHOD (Fixture_X, "X Thin", "[x][persistence][isthmus][thin][function]")
 
 TEST_CASE_METHOD (Fixture_X, "X Thin with Isthmus, and tables", "[x][isthmus][thin][function][table]")
 
 TEST_CASE_METHOD (Fixture_X, "X DistanceMap", "[x][distance][thin]")
 Use distance map in the Select function. More...
 

Detailed Description

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 http://www.gnu.org/licenses/.

Author
Pablo Hernandez-Cerdan (pablo.nosp@m..her.nosp@m.nande.nosp@m.z.ce.nosp@m.rdan@.nosp@m.outl.nosp@m.ook.c.nosp@m.om) Institute of Fundamental Sciences. Massey University. Palmerston North, New Zealand
Date
2018/01/01

Testing class for VoxelComplex.

This file is part of the DGtal library.

Definition in file testVoxelComplex.cpp.

Function Documentation

◆ TEST_CASE_METHOD() [1/18]

TEST_CASE_METHOD ( Fixture_complex_diamond  ,
"Cliques Masks K_0"  ,
""  [clique] 
)

Definition at line 402 of file testVoxelComplex.cpp.

402  {
403  auto &vc = complex_fixture;
404  auto itc = vc.begin(3);
405  for (std::size_t n = 0; n < 10; ++n)
406  ++itc;
407  auto cell = itc->first;
408  Point p_cell = vc.space().uCoords(cell);
409 
410  SECTION("K_0 mask from a pointel") {
411  auto pointel = vc.space().uPointel(p_cell);
412  // auto pointel = vc.space().uPointel(Point{0,0,0});
413 
414  using namespace DGtal::functions;
415  auto k0_mask = vc.K_0(pointel, true);
416 
417  auto &is_critical = k0_mask.first;
418  CHECK(is_critical == false);
419  auto &k0_clique = k0_mask.second;
420  // numer of voxels in clique
421  CHECK(k0_clique.nbCells(3) == 1);
422  }
423 } // test
functions namespace gathers all DGtal functionsxs.
MyPointD Point
Definition: testClone2.cpp:383
SECTION("Testing constant forward iterators")

References SECTION().

◆ TEST_CASE_METHOD() [2/18]

TEST_CASE_METHOD ( Fixture_complex_diamond  ,
"Cliques Masks K_1"  ,
""  [clique] 
)

Definition at line 380 of file testVoxelComplex.cpp.

380  {
381  auto &vc = complex_fixture;
382  auto itc = vc.begin(3);
383  for (std::size_t n = 0; n < 10; ++n)
384  ++itc;
385  auto cell = itc->first;
386  Point p_cell = vc.space().uCoords(cell);
387 
388  SECTION("K_1 mask from a linel") {
389  auto linel =
390  vc.space().uCell(cell.preCell().coordinates + Point{0, 1, 1});
391 
392  using namespace DGtal::functions;
393  auto k1p = vc.K_1(linel, true);
394  auto &is_critical = k1p.first;
395  CHECK(is_critical == true);
396  auto &k1_clique = k1p.second;
397  // numer of voxels in clique
398  CHECK(k1_clique.nbCells(3) == 3);
399  }
400 } // test

References SECTION().

◆ TEST_CASE_METHOD() [3/18]

TEST_CASE_METHOD ( Fixture_complex_diamond  ,
"Cliques Masks K_2"  ,
""  [clique] 
)

Definition at line 341 of file testVoxelComplex.cpp.

341  {
342  auto &vc = complex_fixture;
343  auto itc = vc.begin(3);
344  for (std::size_t n = 0; n < 10; ++n)
345  ++itc;
346  auto cell = itc->first;
347  Point p_cell = vc.space().uCoords(cell);
348  auto neigh6 = vc.space().uProperNeighborhood(cell);
349  REQUIRE(neigh6.size() == 6);
350  KSpace::Cells cells;
351  for(auto & n : neigh6)
352  if(vc.belongs(n)) cells.push_back(n);
353  REQUIRE(cells.size() == 2);
354 
355  std::vector<std::pair<bool, FixtureComplex::Clique>> cliques_p;
356  bool verbose = true;
357  for (auto && cell_n : cells) {
358  auto cell_point = vc.space().uCoords(cell_n);
359  cliques_p.emplace_back(vc.K_2(p_cell, cell_point, verbose));
360  auto &is_critical = cliques_p.back().first;
361  auto &k2_clique = cliques_p.back().second;
362  CHECK(is_critical == true);
363  CHECK(k2_clique.nbCells(3) == 2);
364  }
365 
366  SECTION(" Check same results for different K_2 interfaces") {
367  for (auto && cell_n : cells) {
368  auto co_face = vc.surfelBetweenAdjacentSpels(cell_n, cell);
369 
370  auto cell_point = vc.space().uCoords(cell_n);
371  using namespace DGtal::functions;
372  CHECK(isEqual(vc.K_2(p_cell, cell_point, false).second,
373  vc.K_2(cell, cell_n, false).second) == true);
374  CHECK(isEqual(vc.K_2(p_cell, cell_point, false).second,
375  vc.K_2(co_face, false).second) == true);
376  } // endfor
377  } // then_interfaces
378 } // test
AnyCellCollection< Cell > Cells
bool isEqual(const Container &S1, const Container &S2)
Definition: SetFunctions.h:789
REQUIRE(domain.isInside(aPoint))

References isEqual(), REQUIRE(), and SECTION().

◆ TEST_CASE_METHOD() [4/18]

TEST_CASE_METHOD ( Fixture_complex_diamond  ,
"Faces of voxel"  ,
""  [neighborhood][faces] 
)

Definition at line 180 of file testVoxelComplex.cpp.

181  {
182  auto &vc = complex_fixture;
183  auto &ks = vc.space();
184  bool closed = true;
185  bool no_hint = false;
186  auto not_found = vc.end(3);
187 
188  SECTION("Voxel is in the interior of the complex.") {
189  Point p{0, 0, 2};
190  auto cellMapIt = vc.findCell(3, ks.uSpel(p));
191  CHECK(cellMapIt != not_found);
192  auto cell = cellMapIt->first;
193  auto kfaces = ks.uFaces(cell);
194  CAPTURE(p);
195  CAPTURE(cell);
196  CHECK(kfaces.size() == 26);
197  auto vcBoundary_closed = vc.cellBoundary(cell, closed);
198  CHECK(vcBoundary_closed.size() == 26);
199  auto vcBoundary_no_hint = vc.cellBoundary(cell, no_hint);
200  CHECK(vcBoundary_no_hint.size() == 26);
201  }
202  SECTION("Voxel is in the exterior") {
203  Point p{0, 0, 5};
204  auto cellMapIt = vc.findCell(3, ks.uSpel(p));
205  CHECK(cellMapIt == not_found);
206  auto cell = ks.uSpel(p);
207  auto kfaces = ks.uFaces(cell);
208  CAPTURE(p);
209  CAPTURE(cell);
210  CHECK(kfaces.size() == 26);
211  // We know that is not closed, but checking the differences:
212  auto vcBoundary_closed = vc.cellBoundary(cell, closed);
213  CHECK(vcBoundary_closed.size() == 26);
214  // Right method to call:
215  auto vcBoundary_no_hint = vc.cellBoundary(cell, no_hint);
216  CHECK(vcBoundary_no_hint.size() == 0);
217  }
218  SECTION("Voxel is out, but surrounded by in voxels") {
219  Point p{0, 0, 0};
220  auto cellMapIt = vc.findCell(3, ks.uSpel(p));
221  CHECK(cellMapIt == not_found);
222  auto cell = ks.uSpel(p);
223  auto kfaces = ks.uFaces(cell);
224  CAPTURE(p);
225  CAPTURE(cell);
226  CHECK(kfaces.size() == 26);
227  auto vcBoundary_closed = vc.cellBoundary(cell, closed);
228  CHECK(vcBoundary_closed.size() == 26);
229  auto vcBoundary_no_hint = vc.cellBoundary(cell, no_hint);
230  CHECK(vcBoundary_no_hint.size() == 26);
231  }
232  SECTION("Voxel is in the border") {
233  Point p{0, 0, 3};
234  auto cellMapIt = vc.findCell(3, ks.uSpel(p));
235  CHECK(cellMapIt != not_found);
236  auto cell = cellMapIt->first;
237  auto kfaces = ks.uFaces(cell);
238  CAPTURE(p);
239  CAPTURE(cell);
240  CHECK(kfaces.size() == 26);
241  auto vcBoundary_closed = vc.cellBoundary(cell, closed);
242  CHECK(vcBoundary_closed.size() == 26);
243  auto vcBoundary_no_hint = vc.cellBoundary(cell, no_hint);
244  CHECK(vcBoundary_no_hint.size() == 26);
245  }
246 }
CAPTURE(thicknessHV)

References CAPTURE(), and SECTION().

◆ TEST_CASE_METHOD() [5/18]

TEST_CASE_METHOD ( Fixture_complex_diamond  ,
"Get All Critical Cliques of diamond"  ,
""  [critical][clique] 
)

Definition at line 425 of file testVoxelComplex.cpp.

426  {
427  auto &vc = complex_fixture;
428  using namespace DGtal::functions;
429  SECTION(" Get all criticalCliques() ") {
430  auto criticals = vc.criticalCliques();
431  CHECK(criticals.size() == 4);
432 
433  CHECK(vc.nbCells(3) == 62);
434  CHECK(criticals[3].size() == 18);
435  CHECK(vc.nbCells(2) == 264);
436  CHECK(criticals[2].size() == 108);
437  CHECK(vc.nbCells(1) == 360);
438  CHECK(criticals[1].size() == 168);
439  CHECK(vc.nbCells(0) == 160);
440  CHECK(criticals[0].size() == 32);
441  }
442 }

References SECTION().

◆ TEST_CASE_METHOD() [6/18]

TEST_CASE_METHOD ( Fixture_complex_diamond  ,
"insertVoxel"  ,
""  [insert][close] 
)

Definition at line 120 of file testVoxelComplex.cpp.

120  {
121  auto &vc = complex_fixture;
122  auto &ks = vc.space();
123  auto s3 = vc.nbCells(3);
124  auto s2 = vc.nbCells(2);
125  auto s1 = vc.nbCells(1);
126  auto s0 = vc.nbCells(0);
127  SECTION("insertVoxel in border") {
128  Point p{0, 0, 4};
129  auto vc_new = vc;
130  vc_new.insertVoxelPoint(p);
131  auto sa3 = vc_new.nbCells(3);
132  auto sa2 = vc_new.nbCells(2);
133  auto sa1 = vc_new.nbCells(1);
134  auto sa0 = vc_new.nbCells(0);
135  auto d3 = sa3 - s3;
136  CHECK(d3 == 1);
137  auto d2 = sa2 - s2;
138  CHECK(d2 == 5);
139  auto d1 = sa1 - s1;
140  CHECK(d1 == 8);
141  auto d0 = sa0 - s0;
142  CHECK(d0 == 4);
143  }
144  SECTION("insertVoxel isolated") {
145  Point p{5, 0, 0};
146  auto vc_new = vc;
147  vc_new.insertVoxelCell(ks.uSpel(p));
148  auto sa3 = vc_new.nbCells(3);
149  auto sa2 = vc_new.nbCells(2);
150  auto sa1 = vc_new.nbCells(1);
151  auto sa0 = vc_new.nbCells(0);
152  auto d3 = sa3 - s3;
153  CHECK(d3 == 1);
154  auto d2 = sa2 - s2;
155  CHECK(d2 == 6);
156  auto d1 = sa1 - s1;
157  CHECK(d1 == 12);
158  auto d0 = sa0 - s0;
159  CHECK(d0 == 8);
160  }
161  SECTION("insertVoxel interior") {
162  Point p{0, 2, 0};
163  auto vc_new = vc;
164  vc_new.insertVoxelCell(ks.uSpel(p));
165  auto sa3 = vc_new.nbCells(3);
166  auto sa2 = vc_new.nbCells(2);
167  auto sa1 = vc_new.nbCells(1);
168  auto sa0 = vc_new.nbCells(0);
169  auto d3 = sa3 - s3;
170  CHECK(d3 == 0);
171  auto d2 = sa2 - s2;
172  CHECK(d2 == 0);
173  auto d1 = sa1 - s1;
174  CHECK(d1 == 0);
175  auto d0 = sa0 - s0;
176  CHECK(d0 == 0);
177  }
178 }

References SECTION().

◆ TEST_CASE_METHOD() [7/18]

TEST_CASE_METHOD ( Fixture_complex_diamond  ,
"Neighbors from Object and KSpace ,
""  [neighborhood] 
)

Definition at line 248 of file testVoxelComplex.cpp.

249  {
250  auto &vc = complex_fixture;
251  SECTION(" get neighbors from Kspace") {
252  {
253  Dimension dim_voxel = 3;
254  auto it = vc.begin(dim_voxel);
255  for (std::size_t n = 0; n < 10; ++n)
256  ++it;
257  auto cell = it->first;
258  auto point_from_kspace_1 = cell.preCell().coordinates;
259  size_t expected_num_adjacent_voxels = 12;
260 
261  SECTION("properNeighborhood from KSpace"
262  "does not output all adjacent voxels.") {
263 
264  size_t expected_kspace_neighborhood = 7;
265  auto neigh_k = vc.space().uNeighborhood(cell);
266  CHECK(neigh_k.size() == expected_kspace_neighborhood);
267 
268  auto propN_k = vc.space().uProperNeighborhood(cell);
269  CHECK(propN_k.size() == expected_kspace_neighborhood - 1);
270  }
271 
272  SECTION("Getting associated pointels and voxels from input_cell") {
273  std::set<FixtureComplex::Cell> pointel_set;
274  vc.pointelsFromCell(pointel_set, cell);
275  std::set<FixtureComplex::Cell> voxel_set;
276  for (auto &&p : pointel_set)
277  vc.spelsFromCell(voxel_set, p);
278  SECTION("Gets desired full adjancency for voxels") {
279  CHECK(voxel_set.size() == expected_num_adjacent_voxels);
280  }
281  auto clique = vc.Kneighborhood(cell);
282  CHECK(clique.nbCells(3) == expected_num_adjacent_voxels);
283  }
284  }
285  }
286 }
DGtal::uint32_t Dimension
Definition: Common.h:136

References SECTION().

◆ TEST_CASE_METHOD() [8/18]

TEST_CASE_METHOD ( Fixture_complex_diamond  ,
"Test Simplicity"  ,
""  [simplicity] 
)

Definition at line 288 of file testVoxelComplex.cpp.

288  {
289  auto &vc = complex_fixture;
290  Dimension dim_voxel = 3;
291  auto cit = vc.begin(dim_voxel);
292  for (std::size_t n = 0; n < 10; ++n)
293  ++cit;
294  auto cell = cit->first;
295 
296  SECTION("querying voxel simplicity") {
297  size_t nsimples{0};
298  std::vector<FixtureComplex::Cell> non_simple_cells;
299  for (auto it = vc.begin(dim_voxel); it != vc.end(dim_voxel); ++it) {
300  if (vc.isSimple(it->first))
301  ++nsimples;
302  else
303  non_simple_cells.emplace_back(it->first);
304  }
305 
306  // Border points are simple in diamond.
307  // auto border_size = vc.object().border().size();
308  size_t border_size = 44;
309  REQUIRE(nsimples == border_size);
310  }
311 }

References REQUIRE(), and SECTION().

◆ TEST_CASE_METHOD() [9/18]

TEST_CASE_METHOD ( Fixture_complex_diamond  ,
"Test table wrappers"  ,
""  [table][simple] 
)

Definition at line 313 of file testVoxelComplex.cpp.

314  {
315  auto &vc = complex_fixture;
316  trace.beginBlock("loadTable");
317  vc.setSimplicityTable(functions::loadTable(simplicity::tableSimple26_6));
318  trace.endBlock();
319  auto dim_voxel = 3;
320  auto cit = vc.begin(dim_voxel);
321  for (std::size_t n = 0; n < 10; ++n)
322  ++cit;
323  auto cell = cit->first;
324 
325  SECTION("querying voxel simplicity") {
326  size_t nsimples{0};
327  std::vector<FixtureComplex::Cell> non_simple_cells;
328  for (auto it = vc.begin(dim_voxel); it != vc.end(dim_voxel); ++it) {
329  if (vc.isSimple(it->first))
330  ++nsimples;
331  else
332  non_simple_cells.emplace_back(it->first);
333  }
334 
335  // Border points are simple in diamond.
336  size_t border_size = 44;
337  REQUIRE(nsimples == border_size);
338  }
339 }
void beginBlock(const std::string &keyword="")
double endBlock()
Trace trace
Definition: Common.h:153

References DGtal::Trace::beginBlock(), DGtal::Trace::endBlock(), REQUIRE(), SECTION(), and DGtal::trace.

◆ TEST_CASE_METHOD() [10/18]

TEST_CASE_METHOD ( Fixture_complex_fig4  ,
"Get All Critical Cliques of fig4"  ,
""  [critical][clique] 
)

Definition at line 524 of file testVoxelComplex.cpp.

525  {
526  auto &vc = complex_fixture;
527  using namespace DGtal::functions;
528  SECTION(" Get all criticalCliques() ") {
529  auto criticals = vc.criticalCliques(true);
530  CHECK(criticals.size() == 4);
531 
532  CHECK(vc.nbCells(3) == 12);
533  CHECK(criticals[3].size() == 1);
534  CHECK(vc.nbCells(2) == 64);
535  CHECK(criticals[2].size() == 3);
536  CHECK(vc.nbCells(1) == 109);
537  CHECK(criticals[1].size() == 2);
538  CHECK(vc.nbCells(0) == 58);
539  CHECK(criticals[0].size() == 6);
540  }
541 }

References SECTION().

◆ TEST_CASE_METHOD() [11/18]

TEST_CASE_METHOD ( Fixture_complex_fig4  ,
"zeroSurface and oneSurface"  ,
""  [isSurface][function] 
)

Definition at line 544 of file testVoxelComplex.cpp.

545  {
546  auto &vc = complex_fixture;
547  using namespace DGtal::functions;
548  vc.clear();
549  Point c(0, 0, 0);
550  {
551  vc.insertCell(3, vc.space().uSpel(c));
552  }
553  Point r(0, 1, 0);
554  {
555  vc.insertCell(3, vc.space().uSpel(r));
556  }
557  Point l(0, -1, 0);
558  {
559  vc.insertCell(3, vc.space().uSpel(l));
560  }
561  // Init an object
565  std::unordered_set<typename DGtal::Z3i::Domain::Point>>;
569  auto domain = DGtal::Z3i::Domain(ks_fixture.lowerBound(), ks_fixture.upperBound());
570  DigitalTopology topo(
571  adjF, adjB, DGtal::DigitalTopologyProperties::JORDAN_DT);
572 
573  SECTION("checking zero surfaces of original set") {
574  std::set<Point> zeroSurfacesCells;
575  DigitalSet voxel_set(domain);
576  vc.dumpVoxels(voxel_set);
577  Object object(topo, voxel_set);
578  for (const auto &p : voxel_set) {
579  auto small_obj = object.properNeighborhood(p);
580  if (isZeroSurface(small_obj))
581  zeroSurfacesCells.insert(p);
582  }
583  CHECK(zeroSurfacesCells.size() == 1);
584  }
585 
586  SECTION("checking one surfaces of original set") {
587  Point u(-1, 0, 0);
588  {
589  vc.insertCell(3, vc.space().uSpel(u));
590  }
591  Point d(1, 0, 0);
592  {
593  vc.insertCell(3, vc.space().uSpel(d));
594  }
595 
596  std::set<Point> oneSurfacesCells;
597  DigitalSet voxel_set(domain);
598  vc.dumpVoxels(voxel_set);
599  Object object(topo, voxel_set);
600 
601  for (const auto &p : voxel_set) {
602  auto small_obj = object.properNeighborhood(p);
603  if (isOneSurface(small_obj))
604  oneSurfacesCells.insert(p);
605  }
606  CHECK(oneSurfacesCells.size() == 1);
607  }
608 }
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Aim: Represents a digital topology as a couple of adjacency relations.
TForegroundAdjacency ForegroundAdjacency
TBackgroundAdjacency BackgroundAdjacency
Aim: An object (or digital object) represents a set in some digital space associated with a digital t...
Definition: Object.h:120
HyperRectDomain< Space > Domain
Definition: StdDefs.h:172
DigitalTopology< Adj26, Adj6 > DT26_6
Definition: StdDefs.h:167
bool isZeroSurface(const TObject &small_obj)
bool isOneSurface(const TObject &small_obj)
Domain domain

References domain, DGtal::functions::isOneSurface(), DGtal::functions::isZeroSurface(), DGtal::KhalimskySpaceND< dim, TInteger >::lowerBound(), SECTION(), and DGtal::KhalimskySpaceND< dim, TInteger >::upperBound().

◆ TEST_CASE_METHOD() [12/18]

TEST_CASE_METHOD ( Fixture_isthmus  ,
"Check isthmus"  ,
""  [isthmus][function] 
)

Definition at line 736 of file testVoxelComplex.cpp.

736  {
737  auto &vc = complex_fixture;
738  using namespace DGtal::functions;
739  auto &ks = vc.space();
740  Point x(-1, 4, 0); // oneIsthmus
741  Point y(-1, 1, 0); // twoIsthmus
742 
743  SECTION("checking one isthmus") {
744  std::set<Point> isthmus;
745  for (const auto &p : set_fixture) {
746  if (oneIsthmus(vc, ks.uSpel(p)))
747  isthmus.insert(p);
748  }
749  CHECK(isthmus.size() == 1);
750  auto xit = isthmus.find(x);
751  CHECK(*xit == x);
752  }
753 
754  SECTION("checking 2 isthmus") {
755  std::set<Point> isthmus;
756  for (const auto &p : set_fixture) {
757  if (twoIsthmus(vc, ks.uSpel(p)))
758  isthmus.insert(p);
759  }
760  CHECK(isthmus.size() == 1);
761  auto yit = isthmus.find(y);
762  CHECK(*yit == y);
763  }
764 
765  SECTION("checking 1 and 2 isthmus") {
766  std::set<Point> isthmus;
767  for (const auto &p : set_fixture) {
768  if (skelIsthmus(vc, ks.uSpel(p)))
769  isthmus.insert(p);
770  }
771  CHECK(isthmus.size() == 2);
772  auto xit = isthmus.find(x);
773  auto yit = isthmus.find(y);
774  CHECK(xit != isthmus.end());
775  CHECK(yit != isthmus.end());
776  }
777 }
bool skelIsthmus(const TComplex &vc, const typename TComplex::Cell &cell)
bool twoIsthmus(const TComplex &vc, const typename TComplex::Cell &cell)
bool oneIsthmus(const TComplex &vc, const typename TComplex::Cell &cell)

References DGtal::functions::oneIsthmus(), SECTION(), DGtal::functions::skelIsthmus(), and DGtal::functions::twoIsthmus().

◆ TEST_CASE_METHOD() [13/18]

TEST_CASE_METHOD ( Fixture_isthmus  ,
"Persistence thin"  ,
""  [persistence][isthmus][thin][function] 
)

Definition at line 810 of file testVoxelComplex.cpp.

811  {
812  using namespace DGtal::functions;
813  auto &vc = complex_fixture;
814  auto &ks = vc.space();
815  boost::ignore_unused_variable_warning(ks);
816  SECTION("with skelUltimate") {
817  auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
818  vc, selectRandom<FixtureComplex>, skelUltimate<FixtureComplex>, 0);
819  CHECK(vc_new.nbCells(3) == 1);
820  }
821  SECTION("with skelEnd") {
822  auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
823  vc, selectRandom<FixtureComplex>, skelEnd<FixtureComplex>, 0);
824  CHECK(vc_new.nbCells(3) == 5);
825  }
826  SECTION("with oneIsthmus") {
827  // Not using LUT skel function (slow):
828  //auto vc_new = persistenceAsymetricThinningScheme< FixtureComplex >(
829  // vc, selectRandom<FixtureComplex>, oneIsthmus<FixtureComplex>, 0);
830  //
831  // with LUT:
832  auto table = *functions::loadTable(isthmusicity::tableOneIsthmus);
833  auto pointToMaskMap =
834  *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
835  auto oneIsthmusTable =
836  [&table, &pointToMaskMap](const FixtureComplex &fc,
837  const FixtureComplex::Cell &c) {
838  return skelWithTable(table, pointToMaskMap, fc, c);
839  };
840  auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
841  vc, selectRandom<FixtureComplex>, oneIsthmusTable, 0);
842  CHECK(vc_new.nbCells(3) == 3);
843  }
844  SECTION("with twoIsthmus") {
845  // Not using LUT skel function (slow):
846  //auto vc_new = persistenceAsymetricThinningScheme< FixtureComplex >(
847  // vc, selectRandom<FixtureComplex>, twoIsthmus<FixtureComplex>, 0);
848  //
849  // with LUT:
850  auto table = *functions::loadTable(isthmusicity::tableTwoIsthmus);
851  auto pointToMaskMap =
852  *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
853  auto twoIsthmusTable =
854  [&table, &pointToMaskMap](const FixtureComplex &fc,
855  const FixtureComplex::Cell &c) {
856  return skelWithTable(table, pointToMaskMap, fc, c);
857  };
858  auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
859  vc, selectRandom<FixtureComplex>, twoIsthmusTable, 0);
860  CHECK(vc_new.nbCells(3) == 1);
861  }
862  SECTION("with skelIsthmus") {
863  // Not using LUT skel function (slow):
864  //auto vc_new = persistenceAsymetricThinningScheme< FixtureComplex >(
865  // vc, selectRandom<FixtureComplex>, skelIsthmus<FixtureComplex>, 0);
866  //
867  // with LUT:
868  auto table = *functions::loadTable(isthmusicity::tableIsthmus);
869  auto pointToMaskMap =
870  *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
871  auto isthmusTable = [&table,
872  &pointToMaskMap](const FixtureComplex &fc,
873  const FixtureComplex::Cell &c) {
874  return skelWithTable(table, pointToMaskMap, fc, c);
875  };
876  auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
877  vc, selectRandom<FixtureComplex>, isthmusTable, 0);
878  CHECK(vc_new.nbCells(3) == 3);
879  }
880 }
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)
KSpace::Cell Cell

References SECTION(), and DGtal::functions::skelWithTable().

◆ TEST_CASE_METHOD() [14/18]

TEST_CASE_METHOD ( Fixture_isthmus  ,
"Thin complex"  ,
""  [isthmus][thin][function] 
)

Definition at line 778 of file testVoxelComplex.cpp.

778  {
779  using namespace DGtal::functions;
780  auto &vc = complex_fixture;
781  auto &ks = vc.space();
782  boost::ignore_unused_variable_warning(ks);
783  SECTION("with skelUltimate") {
784  auto vc_new = asymetricThinningScheme<FixtureComplex>(
785  vc, selectFirst<FixtureComplex>, skelUltimate<FixtureComplex>);
786  CHECK(vc_new.nbCells(3) == 1);
787  }
788  SECTION("with skelEnd") {
789  auto vc_new = asymetricThinningScheme<FixtureComplex>(
790  vc, selectFirst<FixtureComplex>, skelEnd<FixtureComplex>);
791  CHECK(vc_new.nbCells(3) == 5);
792  }
793  SECTION("with oneIsthmus") {
794  auto vc_new = asymetricThinningScheme<FixtureComplex>(
795  vc, selectRandom<FixtureComplex>, oneIsthmus<FixtureComplex>);
796  CHECK(vc_new.nbCells(3) == 3);
797  }
798  SECTION("with twoIsthmus") {
799  auto vc_new = asymetricThinningScheme<FixtureComplex>(
800  vc, selectRandom<FixtureComplex>, twoIsthmus<FixtureComplex>);
801  CHECK(vc_new.nbCells(3) == 1);
802  }
803  SECTION("with skelIsthmus") {
804  auto vc_new = asymetricThinningScheme<FixtureComplex>(
805  vc, selectRandom<FixtureComplex>, skelIsthmus<FixtureComplex>);
806  CHECK(vc_new.nbCells(3) == 3);
807  }
808 }

References SECTION().

◆ TEST_CASE_METHOD() [15/18]

TEST_CASE_METHOD ( Fixture_isthmus  ,
"Thin disconnected complex"  ,
""  [isthmus][thin][function] 
)

Definition at line 716 of file testVoxelComplex.cpp.

717  {
718  using namespace DGtal::functions;
719  auto &vc = complex_fixture;
720  auto &ks = vc.space();
721  boost::ignore_unused_variable_warning(ks);
722  Point x(-1, 4, 0);
723  set_fixture.erase(x);
724  // Delete one point and reconstruct complex.
725  /* obj_fixture.pointSet().erase(x); */
726  vc.clear();
727  vc.construct(set_fixture);
728  SECTION("with skelUltimate") {
729  auto vc_new = asymetricThinningScheme<FixtureComplex>(
730  vc, selectFirst<FixtureComplex>, skelUltimate<FixtureComplex>);
731  CHECK(vc_new.nbCells(3) == 2);
732  }
733 }

References SECTION().

◆ TEST_CASE_METHOD() [16/18]

TEST_CASE_METHOD ( Fixture_X  ,
"X DistanceMap"  ,
""  [x][distance][thin] 
)

Use distance map in the Select function.

Definition at line 1059 of file testVoxelComplex.cpp.

1059  {
1060  using namespace DGtal::functions;
1061  auto &vc = complex_fixture;
1062  auto &ks = vc.space();
1063  boost::ignore_unused_variable_warning(ks);
1064  using Predicate = Z3i::DigitalSet;
1067  bool verbose = true;
1068  SECTION("Fixture_X Distance Map") {
1069  trace.beginBlock("With a Distance Map");
1070  L3Metric l3;
1071  DT dt(set_fixture.domain(), set_fixture, l3);
1072  // Create wrap around selectMaxValue to use the thinning.
1073  auto selectDistMax = [&dt](const FixtureComplex::Clique &clique) {
1074  return selectMaxValue<DT, FixtureComplex>(dt, clique);
1075  };
1076  SECTION("asymetricThinning"){
1077  auto vc_new = asymetricThinningScheme<FixtureComplex>(
1078  vc, selectDistMax, skelEnd<FixtureComplex>, verbose);
1079  }
1080  SECTION("persistenceThinning"){
1081  auto table = *functions::loadTable(isthmusicity::tableOneIsthmus);
1082  auto pointToMaskMap =
1083  *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
1084  auto oneIsthmusTable =
1085  [&table, &pointToMaskMap](const FixtureComplex &fc,
1086  const FixtureComplex::Cell &c) {
1087  return skelWithTable(table, pointToMaskMap, fc, c);
1088  };
1089  int persistence = 3;
1090  auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
1091  vc, selectDistMax, oneIsthmusTable,
1092  persistence, verbose);
1093  // SECTION( "visualize the thining" ){
1094  // int argc(1);
1095  // char** argv(nullptr);
1096  // QApplication app(argc, argv);
1097  // Viewer3D<> viewer(ks_fixture);
1098  // viewer.show();
1099  //
1100  // viewer.setFillColor(Color(200, 200, 200, 100));
1101  // for ( auto it = vc_new.begin(3); it!= vc_new.end(3); ++it )
1102  // viewer << it->first;
1103  //
1104  // // All kspace voxels
1105  // viewer.setFillColor(Color(40, 40, 40, 10));
1106  // for ( auto it = vc.begin(3); it!= vc.end(3); ++it )
1107  // viewer << it->first;
1108  //
1109  // viewer << Viewer3D<>::updateDisplay;
1110  // app.exec();
1111  // }
1112  }
1113 
1114  }
1115 
1116  trace.endBlock();
1117 }
Aim: Implementation of the linear in time distance transformation for separable metrics.
Aim: implements separable l_p metrics with exact predicates.
DigitalSetSelector< Domain, BIG_DS+HIGH_BEL_DS >::Type DigitalSet
Definition: StdDefs.h:173

References DGtal::Trace::beginBlock(), dt, DGtal::Trace::endBlock(), SECTION(), DGtal::functions::skelWithTable(), and DGtal::trace.

◆ TEST_CASE_METHOD() [17/18]

TEST_CASE_METHOD ( Fixture_X  ,
"X Thin with  Isthmus,
and tables"  ,
""  [x][isthmus][thin][function][table] 
)

Definition at line 1004 of file testVoxelComplex.cpp.

1005  {
1006  using namespace DGtal::functions;
1007  auto &vc = complex_fixture;
1008  auto &ks = vc.space();
1009  boost::ignore_unused_variable_warning(ks);
1010  bool verbose = true;
1011 
1012  // Disabled to reduce test time
1013  // SECTION("Compute with skelIsthmus") {
1014  // trace.beginBlock("Fixture_X skelIsthmus");
1015  // auto vc_new = asymetricThinningScheme<FixtureComplex>(
1016  // vc, selectRandom<FixtureComplex>, skelIsthmus<FixtureComplex>,
1017  // verbose);
1018  // trace.endBlock();
1019  // }
1020  SECTION("Compute with skelWithTable (isIsthmus)") {
1021  trace.beginBlock("Fixture_X skelIsthmus with table");
1022  auto table = *functions::loadTable(isthmusicity::tableIsthmus);
1023  auto pointToMaskMap =
1024  *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
1025  auto skelWithTableIsthmus =
1026  [&table, &pointToMaskMap](const FixtureComplex &fc,
1027  const FixtureComplex::Cell &c) {
1028  return skelWithTable(table, pointToMaskMap, fc, c);
1029  };
1030 
1031  auto vc_new = asymetricThinningScheme<FixtureComplex>(
1032  vc, selectRandom<FixtureComplex>, skelWithTableIsthmus, verbose);
1033 
1034  trace.endBlock();
1035  }
1036 
1037  SECTION("Compute with skelWithTable (isIsthmus) and empty Object") {
1038  trace.beginBlock("Fixture_X skelIsthmus with table (empty objectSet)");
1039  vc.setSimplicityTable(
1040  functions::loadTable(simplicity::tableSimple26_6));
1041  vc.clear();
1042  auto table = *functions::loadTable(isthmusicity::tableIsthmus);
1043  auto pointToMaskMap =
1044  *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
1045  auto skelWithTableIsthmus =
1046  [&table, &pointToMaskMap](const FixtureComplex &fc,
1047  const FixtureComplex::Cell &c) {
1048  return skelWithTable(table, pointToMaskMap, fc, c);
1049  };
1050 
1051  auto vc_new = asymetricThinningScheme<FixtureComplex>(
1052  vc, selectRandom<FixtureComplex>, skelWithTableIsthmus, verbose);
1053 
1054  trace.endBlock();
1055  }
1056 }

References DGtal::Trace::beginBlock(), DGtal::Trace::endBlock(), SECTION(), DGtal::functions::skelWithTable(), and DGtal::trace.

◆ TEST_CASE_METHOD() [18/18]

TEST_CASE_METHOD ( Fixture_X  ,
"X Thin"  ,
""  [x][persistence][isthmus][thin][function] 
)

Definition at line 977 of file testVoxelComplex.cpp.

978  {
979  using namespace DGtal::functions;
980  auto &vc = complex_fixture;
981  auto &ks = vc.space();
982  boost::ignore_unused_variable_warning(ks);
983  bool verbose = true;
984  SECTION(
985  "persistence value of 1 is equivalent to the assymetric algorithm") {
986  auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
987  vc, selectFirst<FixtureComplex>, skelEnd<FixtureComplex>, 1,
988  verbose);
989 
990  auto vc_assymetric = asymetricThinningScheme<FixtureComplex>(
991  vc, selectFirst<FixtureComplex>, skelEnd<FixtureComplex>, true);
992  // 10% tolerance
993  CHECK(vc_assymetric.nbCells(3) ==
994  Approx(vc_new.nbCells(3)).epsilon(0.1));
995  }
996  SECTION("persistence value: infinite is equivalent to ultimate skeleton") {
997  auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
998  vc, selectRandom<FixtureComplex>, skelEnd<FixtureComplex>, 100,
999  verbose);
1000  REQUIRE(vc_new.nbCells(3) == 1);
1001  }
1002 }

References REQUIRE(), and SECTION().