DGtal 1.4.0
Loading...
Searching...
No Matches
Image and digital object import/export
Authors
David Coeurjolly, Bertrand Kerautret, Martial Tola, Pierre Gueth

This part of the manual describes how to import and export images and main DGtal objects from/to various formats.

Introduction

In DGtal, file readers and writers are located in the "io/readers/" and "io/writers/" folders respectively. Most of them are dedicated to image format import/export but some other DGtal data structures can have such tools (e.g. point set/mesh readers).

Before going into details, let us first present an interesting tool for image visualisation or image export: predefined colormaps to convert scalars or to (red,green,blue) triplets.

Colormaps

Colormap models satisfy the CColormap concept. For short, a colormap is parametrized by a scalar value template type (Value). When constructed from two min and max values (of type Value), the colormap offers an operator returning a DGtal::Color for each value v in the interval [min,max].

For example, RandomColorMap returns a random color for each value v. More complex colormaps (GradientColorMap, HueShadeColorMap, ...) offer better colormap for scientific visualisation purposes.

Example of predefined colormaps

Beside colormaps, TickedColorMap is a colormap adapter that adds ticks. For example, you can adapt a Black-Red gradient colormap to add regular white ticks (see usage in testTickedColorMap.cpp):

Colormaps with regular ticks

Ticks can be regularly spaced or explicitly given by the user.

In some situations, we may have to convert colors into scalar values (see below). In this case, basic conversion functors are available in the DGtal::functors namespace. For example, you would find in this namespace a DGtal::functors::RedChannel converter or a DGtal::functors::MeanChannels converter.

Hence, to implement a functor taking values and returning the red channel of a colormap, you just have to compose the two functors with the help of the Composer:

#include "DGtal/base/BasicFunctors.h"
#include "DGtal/io/colormaps/GradientColorMap.h"
#include "DGtal/io/colormaps/BasicColorToScalarFunctors.h"
typedef GradientColorMap<unsigned char, CMAP_JET > JetMap;
typedef functors::RedChannel RedChan;
typedef Composer< JetMap, RedChan, unsigned char> RedFunctor;
RedFunctor redFunctor( JetMap(0,255), RedChan() );
PGMWriter<Image, RedFunctor>::exportPGM("export-jet-red.pgm",image, redFunctor);
static bool exportPGM(const std::string &filename, const Image &aImage, const Functor &aFunctor=Functor(), bool saveASCII=false, bool topbotomOrder=true)

Image file formats

We first detail import/export format for DGtal images. Please refer to Images for details on images in DGtal and their associated concepts. First of all:

  • Image readers are classes templated by an image container type.
  • Image writers are classes templated by an image type and a functor to convert image values to the value type of the writer file format.

Hence, for image writers, some functors may return a DGtal::Color or a scalar value depending on the writer.

Image Writers

Dimension Name Description Functor requirements Class name Comment
2D PGM Grayscale netpbm image format the functor should return an unsigned char PGMWriter http://netpbm.sourceforge.net/
PPM Color netpbm image format the functor should return a DGtal::Color PPMWriter http://netpbm.sourceforge.net/
any stb_image format Color image format (png,jpg, bmp,tga ) the functor must return a DGtal::Color STBWriter
any 2D ITK format Grayscale or 2D ITK image the functor should return a ITKIOTrait<Image::Value>::ValueOut ITKWriter with WITH_ITK build flag, http://www.itk.org/
3D PGM3D Grayscale netpbm image format the functor should return an unsigned char PGMWriter
PPM3D Color netpbm image format the functor should return a DGtal::Color PPMWriter
Vol Volumetric file format the functor should return an unsigned char VolWriter Simplevol project, http://liris.cnrs.fr/david.coeurjolly
Longvol Volumetric file format (long) the functor should return a DGtal::uint64_t LongvolWriter Simplevol project, http://liris.cnrs.fr/david.coeurjolly
HDF5 HDF5 file with 3D UInt8 image dataset(s) the functor should return a DGtal::uint8_t HDF5Writer with WITH_HDF5 build flag, http://www.hdfgroup.org/HDF5/
any 3D ITK format Any 3D ITK image the functor should return a ITKIOTrait<Image::Value>::ValueOut ITKWriter with WITH_ITK build flag, http://www.itk.org/
nD Raw8 raw binary file format on 8bits the functor should return an unsigned char RawWriter
Raw16 raw binary file format on 16bits the functor should return an unsigned short RawWriter
Raw32 raw binary file format on 32bits the functor should return an unsigned int RawWriter
Raw raw binary file format for any type the functor should return the same type as specified in the template parameter of RawWriter::exportRaw RawWriter
Note
Since DGtal doesn't integrate ITK by default, ITK image should by writen directly using the ITKWriter class.
Image image;
DGtal::ITKReader<Image>::exportITK("example.mha", image);
Aim: Import a 2D/3D Image using the ITK formats.
Definition ITKReader.h:80
ImageContainerBySTLVector< Domain, Value > Image

For scalar value format (PGM, Vol, Longvol, Raw, ...), the associated template class have a default functor type. Hence, if you just want to cast your image values to the file format value type (e.g. "unsigned char" for Vol), do not specify any functor.

The class GenericWriter allows to automatically export any image (2d, 3d, nd) from its filename. The class is templated with an image container type, a dimension value (given by default by the image container dimension), a value type, (also given by default by the image container) and a functor type (by default set to the DefaultFunctor type).

To use it you need first to include the following header:

After constructing and filling an image (anImage2D or anImage3D), by default you can save it with:

GenericWriter<Image3D>::exportFile("aFilename.pgm3d", anImage3D);
GenericWriter<Image2D>::exportFile("aFilename.pgm", anImage2D);
static bool exportFile(const std::string &filename, const TContainer &anImage, const TFunctor &aFunctor=TFunctor())

As the other export functions, a functor can be used as optional argument (as given in the previous example):

GenericWriter<Image2D, redFunctor>::exportFile("aFilename.pgm", anImage2D, redFunctor);

If you don't need to specify special functor and if don't need to change default image type, you can use a less generic writer with the stream operator and the string filename:

anImage3D >> "aFilename.pgm3d";
anImage3D >> "aFilename.vol";
anImage2D >> "aFilename.pgm";
Note
Naturally, the stream operator hide a default functor (c++ cast to a given type).

To write color images, you need to use a functor which transform a scalar value into a Color. You can use the previous Colormaps :

DGtal::HueShadeColorMap<double> hueColorMap (-50.0, 50.0);
//...
DGtal::GenericWriter<Image2D, 2, double, DGtal::HueShadeColorMap<double> >::exportFile("aFilename.ppm", anImage, hueColorMap );
Aim: This class template may be used to (linearly) convert scalar values in a given range into a colo...
Aim: Provide a mechanism to save image (2D or 3D) into file with the best saver loader according to a...

Image Readers

Dimension Name Description Class name Comment
2D PGM Grayscale netpbm image format PGMReader http://netpbm.sourceforge.net/
any stb format Any file format in the stb_image library (bmp,png,jpg,tga, gif) STBReader
HDF5 HDF5 file with 2D image dataset(s) HDF5Reader with WITH_HDF5 build flag, http://www.hdfgroup.org/HDF5/
any 2D ITK format Any file format in the ITK library (png, jpg, mhd, mha, ...) ITKReader with WITH_ITK build flag, http://www.itk.org/
3D PGM3D Grayscale netpbm image format PGMReader
PGM Same as PGM3D but with same header as in 2D (P2 or P5) PGMReader
DICOM Medical format (from scanners, with the use of ITK library) DicomReader http://medical.nema.org/
Vol Volumetric file format VolReader Simplevol project, http://liris.cnrs.fr/david.coeurjolly
Longvol Volumetric file format (long) LongvolReader Simplevol project, http://liris.cnrs.fr/david.coeurjolly
HDF5 HDF5 file with 3D UInt8 image dataset(s) HDF5Reader with WITH_HDF5 build flag, http://www.hdfgroup.org/HDF5/
any 3D ITK format Any file format in the ITK library (mhd, mha, ...) ITKReader with WITH_ITK build flag, http://www.itk.org/
nD Raw8 raw binary file format on 8bits RawReader
Raw16 raw binary file format on 16bits RawReader
Raw32 raw binary file format on 32bits RawReader
Raw raw binary file format for any type RawReader
Note
Since DGtal doesn't integrate ITK by default, ITK image should by read directly using the ITKReader class.
static Image importITK(const std::string &filename, const TFunctor &aFunctor=TFunctor(), bool shiftDomainUsingOrigin=true)

The class GenericReader allows to automatically import any image (2d, 3d, nd) from its filename. The class is templated with an image container type, a dimension value (given by default by the image container dimension), a value type, (also given by default by the image container). Note that the reader choice between 8 bits or 32 bits is automatically done according to the templated image container type. So you can have an DGtal::IOException if you try to read a 8 bits raw image from an unsigned int image type (choose an 8 bits type like unsigned char or explicitly call the specific reader RawReader::importRaw8).

#include "DGtal/io/readers/GenericReader.h"
#include "DGtal/helpers/StdDefs.h"

Use the same import function for both 2D or 3D images:

Image3D an3Dimage= DGtal::GenericReader<Image3D>::import("example.vol");
Image2D an2Dimage= DGtal::GenericReader<Image2D>::import("example.pgm");
static TContainer import(const std::string &filename, std::vector< unsigned int > dimSpace=std::vector< unsigned int >())

Details on the Vol/Longvol formats

The Vol and Longvol formats are described on the simplevol project website (http://liris.cnrs.fr/david.coeurjolly/code/simplevol.html). Basically, the format consists in:

  • an ASCII header with for instance the image size and the Vol format version, ending with a ".". Mandatory information are the size (X, Y, Z) and the format version (Version). E.g.
    Center-X: 5
    Center-Y: 5
    Center-Z: 5
    X: 11
    Y: 11
    Z: 11
    Voxel-Size: 1
    Alpha-Color: 0
    Voxel-Endian: 0
    Int-Endian: 0123
    Version: 3
    .
    HalfEdgeDataStructure::Size Size
  • a binary chunck with linearized image values. In "Version 2" of Vol and Longvol, the binary chunck is simply a raw export of image values (little endian for Longvol entries). In "Version 3", the binary values are compressed using zlib (default version when using the DGtal reader and writer).

If you want to export an image to "Version 2" Vol or a Longvol, just add a false flag when exporting. For instance:

Aim: Export a 3D Image using the Vol formats.
Definition VolWriter.h:69
Note
"Version 1" Vol or Longvol files are no longer supported in DGtal readers/writers.

Other geometrical formats

Point list format in n-D

The static class PointListReader allows to read discrete points represented in simple file where each line represent a single point.

3D Surface Mesh

The static class MeshReader allows to import Mesh from OBJ, OFF or OFS file format. Actually this class can import surface mesh (Mesh) where faces are potentially represented by triangles, quadrilaters and polygons. Notes that Mesh can be directly displayed with Viewer3D.

The mesh importation can be done automatically from the extension file name by using the "<<" operator. For instance (see. Import 3D mesh from OFF file ):

std::string inputFilename = examplesPath + "samples/tref.off";
// Since the input points are not necessary integers we use the PointD3D from Display3D.
Mesh<Viewer3D<>::RealPoint> anImportedMesh;
anImportedMesh << inputFilename;

You can also export a Mesh object by using the operator (">>"). Notes that the class Display3D permits also to generate a Mesh which can be exported (see. Export 3D mesh in OFF and OBJ format).

Examples

Importing a 3D digital set from volume file:

Importing and visualizing a digital set from a vol file can be done in few code lines. (see. digitalSetFromVol.cpp).

First we select the Image type with int:

#include "DGtal/io/readers/VolReader.h"
#include "DGtal/images/ImageSelector.h"
#include "DGtal/images/imagesSetsUtils/SetFromImage.h"
#include "DGtal/helpers/StdDefs.h"
...
ImageContainerBySTLVector< Domain, Value > Type

Then the initial image is imported:

Image image = VolReader<Image>::importVol(inputFilename);
static ImageContainer importVol(const std::string &filename, const Functor &aFunctor=Functor())

Afterwards the set is thresholded in ]0,255[:

Z3i::DigitalSet set3d (image.domain());
Viewer3D<> viewer;
viewer.show();
viewer << SetMode3D(image.domain().className(), "BoundingBox");
viewer << set3d << image.domain() << Viewer3D<>::updateDisplay;
DigitalSetSelector< Domain, BIG_DS+HIGH_BEL_DS >::Type DigitalSet
Definition StdDefs.h:173
static void append(Set &aSet, const ForegroundPredicate &isForeground, typename Image::Domain::ConstIterator itBegin, typename Image::Domain::ConstIterator itEnd)

Then you will obtain the following visualisation:

3D digital set from volumetric file (.vol)

Import 3D point list from file

The example digitalSetFromPointList.cpp shows a simple example of 3d set importation:

vector<Z3i::Point> vectPoints= PointListReader<Z3i::Point>::getPointsFromFile(inputFilename);
for(unsigned int i=0; i<vectPoints.size();i++){
viewer << vectPoints.at(i);
}
static std::vector< TPoint > getPointsFromFile(const std::string &filename, std::vector< unsigned int > aVectPosition=std::vector< unsigned int >())

We can change the way to select the coordinate field:

vector<unsigned int> vPos;
vPos.push_back(0);
vPos.push_back(2);
vPos.push_back(1);
vectPoints= PointListReader<Z3i::Point>::getPointsFromFile(inputFilename, vPos);
viewer<< CustomColors3D(QColor(255,0,0), QColor(255,0,0));
for(unsigned int i=0; i<vectPoints.size();i++){
viewer << vectPoints.at(i);
}
viewer << Viewer3D<>::updateDisplay;

You may obtain the following visualisation:

Visualisation of 3d imported point list

Import 3D mesh from OFF file

The following example meshFromOFF.cpp shows in few lines how to import and display an OFF 3D mesh. Add the following headers to access to OFF reader and Viewer3D:

#include "DGtal/io/readers/MeshReader.h"

then import an example ".off" file from the example/sample directory:

std::string inputFilename = examplesPath + "samples/tref.off";
// Since the input points are not necessary integers we use the PointD3D from Display3D.
Mesh<Viewer3D<>::RealPoint> anImportedMesh;
anImportedMesh << inputFilename;

Display the result:

viewer.setLineColor(DGtal::Color(150,0,0,254));
viewer << anImportedMesh;
viewer << Viewer3D<>::updateDisplay;

You may obtain the following visualisation:

Visualisation of 3d imported Mesh

You can also import large scale mesh, like the one of classic Angel scan ( available here: http://www.cc.gatech.edu/projects/large_models/ )

Visualisation of the 3d angel

Export 3D mesh in OFF and OBJ format

The following example display3DToOFF.cpp shows in few lines how to export in OFF format a DigitalSet object. This object will be exported with a Display3D object (see. display3DToOFF.cpp).

typedef ImageSelector < Z3i::Domain, int>::Type Image;
Image image = VolReader<Image>::importVol(inputFilename);
Z3i::DigitalSet set3d (image.domain());
viewer << set3d ;
viewer >> "exportMeshToOFF.off";

Notes that the export can also be done in two steps:

// The parameter true is used to specify that we store the face colors.
Mesh aMesh(true);
viewer >> aMesh;
aMesh >> "exporMeshToOFF.off"

The resulting mesh can be visualized for instance by using meshlab;

Visualization of the exported mesh

This code can be useful if you want to generate illustrations in the U3D format. For instance by using the U3D/PDF export from MeshLab or JReality ( www3.math.tu-berlin.de/jreality/). You can for instance generate some exports in pdf like this example:

Visualization in PDF of an exported Digital object.

(see this pdf file: http://dgtal.org/wp/wp-content/uploads/2010/10/3dKSSurfaceExtractionExport.pdf )