DGtal 1.4.0
Loading...
Searching...
No Matches
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.
 

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
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(Container1 &c1, Container2 &c2)
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()
DGtal::CountedPtr< boost::dynamic_bitset<> > loadTable(const std::string &input_filename, const unsigned int known_size, const bool compressed=true)
Trace trace
Definition Common.h:153

References DGtal::Trace::beginBlock(), DGtal::Trace::endBlock(), DGtal::functions::loadTable(), 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(
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::JORDAN_DT, 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 SECTION().

◆ 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 =
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 =
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 =
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< std::unordered_map< TPoint, NeighborhoodConfiguration > > mapZeroPointNeighborhoodToConfigurationMask()

References DGtal::functions::loadTable(), DGtal::functions::mapZeroPointNeighborhoodToConfigurationMask(), and SECTION().

◆ 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 =
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(), DGtal::functions::loadTable(), DGtal::functions::mapZeroPointNeighborhoodToConfigurationMask(), SECTION(), 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 =
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 =
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(), DGtal::functions::loadTable(), DGtal::functions::mapZeroPointNeighborhoodToConfigurationMask(), SECTION(), 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().