DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Helpers for digital surfaces

Table of Contents

Author(s) of this documentation:
Bertrand Kerautret and Jacques-Olivier Lachaud.

Part of the Topology package.

This part of the manual describes how to use the helper class Surfaces to build digital surfaces, closed or open, or contours within digital surfaces. A lot of the ideas, concepts, algorithms, documentation and code is a backport from ImaGene.

All the code presented here require:

#include "DGtal/topology/helpers/Surfaces.h"
Note:
This class is useful if you wish only to obtain the set of surfels of a given digital surface or if you wish to obtain 2D contours (in 2D or 3D). If you require more advanced operations on surfaces (for instance using afterwards the topology defined on the surface), it is better to wrap a DigitalSurface object around your surface of interest, see Digital surfaces.

The 2D case: the boundary is a sequence of cells

The surfaces classes offers the possibility to extract an open or closed contour as a sequence of surfels obtained from a DigitalSet and a starting surfel. The full code of this example is available in file ctopo-2.cpp .

The first step to extract the surfel boudary of a 2D digital set is to obtain an initial boundary surfel:

aCell = Surfaces<Z2i::KSpace>::findABel(ks, set2d);

The first surfel can also be displayed in red with Board2D:

Board2D board;
board << image.domain() << set2d; // display domain and set
board << CustomStyle( aCell.className(), new CustomColors( Board2D::Color( 255, 0, 0 ),
Board2D::Color( 192, 0, 0 ) ));
board << aCell;
ctopo2a.png
Start surfel before a tracking (in red).

Then you can extract the sequence of consecutive surfels:

std::vector<Z2i::SCell> vectBdrySCell;
SurfelAdjacency<2> SAdj( true );
ks, SAdj, set2d, aCell );

and display it:

GradientColorMap<int> cmap_grad( 0, vectBdrySCell.size() );
cmap_grad.addColor( Board2D::Color( 50, 50, 255 ) );
cmap_grad.addColor( Board2D::Color( 255, 0, 0 ) );
cmap_grad.addColor( Board2D::Color( 255, 255, 10 ) );
unsigned int d=0;
std::vector<Z2i::SCell>::iterator it;
for ( it=vectBdrySCell.begin() ; it != vectBdrySCell.end(); it++ ){
board<< CustomStyle((*it).className() ,
new CustomColors( Board2D::Color::Black,
cmap_grad( d )))<< *it;
d++;
}

You will obtain the following ordered sequence of surfels:

ctopo2b.png
Tracking of a closed 2D contour.

The resulting sequence of surfels does not necessary present an open contour (try for instance image "samples/circleR10modif.pgm"):

ctopo2c.png
Tracking of an open 2D contour.

Tracking a 3D boundary to build a surface.

With only few modifications we can apply the same extraction on 3D surfel set. The file ctopo-2-3d.cpp shows the same previous example adapted in 3D.

with the same code we can get a surfel boundary:

From this SCell all the surfel connected sets can be extracted:

// Extracting all boundary surfels which are connected to the initial boundary Cell.
ks,SAdj, set3d, aCell );

To see both initial surfel and the surfel set, we can use the transparent mode:

viewer << SetMode3D((*(vectBdrySCellALL.begin())).className(), "Transparent");

To avoid surfel superposition we need to increase with a small shift the surfel size, for this purpose you can add the following key:

or use the special mode "Highlighted" which increase automaticly the surfel size.

You can obtain for instance the following visualisation:

ctopo3dSurfel.png
Tracking surfaces in 3D (start surfel in green).

Since in 3D there are several choice for the direction used to exctract surfel boundary, we can specify the constant direction need to drive the surfel extraction:

// Extract the boundary contour associated to the initial surfel in its first direction
ks, *(ks.sDirs( aCell )),SAdj, set3d, aCell );

After extracting the two surfels cut you may obtain the following visualisation:

ctopo3dSurfelCut.png
Tracking surfaces and slices in 3D (start surfel in green).

Extracting surface connected components

The class Surfaces provides other useful function to extract connected boundary surfels from a digital set and given a surfel adjacency definition. The example 3dKSSurfaceExtraction.cpp shows an example of such an extraction.

From a domain we construct a DigitalSet inserting points under given conditions (see. 3dKSSurfaceExtraction.cpp for more details)

#include "DGtal/helpers/Surfaces.h"
#include "DGtal/topology/KhalimskySpaceND.h"
...
Domain domain( p1, p2);
DigitalSet diamond_set( domain );
...
diamond_set.insertNew( *it );
....

With this domain bounding points (p1, p2), a KhalimskySpace is constructed and a SurfelAdjacency definition is introduced.

KSpace K;
K.init(p1, p2, true);
SurfelAdjacency<3> SAdj( true );

Then we can extract all connected surfels from the digitalSet surface :

SetPredicate<DigitalSet> shape_set_predicate( diamond_set );
Surfaces<KSpace>::extractAllConnectedSCell(vectConnectedSCell,K, SAdj, shape_set_predicate);

After processing a simple display of each resulting connecting component you can obtain such a visualisation:

KSurfelsConnectedOrientExt.png
Visualisation of connected set of SignefKhalimskySpaceND

Here since the last argument is set to true, the resulting SignedKhalimskySpaceND are signed in order to indicate the direction of exterior. You can also get the SignefKhalimskySpaceND with default sign:

Surfaces<KSpace>::extractAllConnectedSCell(vectConnectedSCell,K, SAdj, shape_set_predicate, false);

and you will get the resulting cell display:

KSurfelsConnectedDefaultOrient.png
Visualisation of connected set of oriented surfels of a KhalimskySpaceND.