Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MagickWriter in generic writer #1306

Merged
merged 15 commits into from
Feb 4, 2018
6 changes: 2 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,16 @@ addons:
- libqglviewer-dev
- libinsighttoolkit3-dev
- libfftw3-dev
- g++-5
- gcc-5

before_install:
- if [ "$CXX" = "g++" ]; then export CXX="g++-5" CC="gcc-5"; fi
- export DEC="false";
- source .travis/before_global.sh
- echo "C++ ===> $CXXCOMPILER"
- if [ $CONFIG == "Debug,Cairo,QGLviewer,HDF5,EIGEN" ]; then source .travis/install_eigen.sh ; cd $TRAVIS_BUILD_DIR; fi
- echo $EIGEN_ROOT
- if [ $CONFIG == "Documentation" ]; then export NEEDEXAMPLESANDTESTS="false"; export NEEDCORE="false"; export BUILD_DOC="true"; if [ $OriginalRepo == "true" ]; then if [ $TRAVIS_PULL_REQUEST == "false" ]; then export UPLOAD_DOC="true"; fi; fi; fi
- if [ $CONFIG == "Debug,Magick,GMP,ITK,FFTW3" ]; then export BTYPE="-DCMAKE_BUILD_TYPE=Debug -DWITH_MAGICK=true -DWITH_GMP=true -DWITH_FFTW3=true -DBUILD_TESTING=ON -DWARNING_AS_ERROR=ON"; fi
- if [ $CONFIG == "Debug,Cairo,QGLviewer,HDF5,EIGEN" ]; then export BTYPE="-DCMAKE_BUILD_TYPE=Debug -DWITH_HDF5=true -DWITH_CAIRO=true -DWITH_QGLVIEWER=true -DBUILD_TESTING=ON -DWITH_EIGEN=true -DWARNING_AS_ERROR=OFF -DEIGEN3_INCLUDE_DIR='$EIGEN_ROOT/include/eigen3'"; fi
- if [ $CONFIG == "Debug,Cairo,QGLviewer,HDF5,EIGEN" ]; then export DEC="true"; export BTYPE="-DCMAKE_BUILD_TYPE=Debug -DWITH_HDF5=true -DWITH_CAIRO=true -DWITH_QGLVIEWER=true -DBUILD_TESTING=ON -DWITH_EIGEN=true -DWARNING_AS_ERROR=OFF -DEIGEN3_INCLUDE_DIR='$EIGEN_ROOT/include/eigen3'"; fi
- if [ $CONFIG == "DGtalTools" ]; then export NEEDEXAMPLESANDTESTS="false"; export BTYPE="-DCMAKE_BUILD_TYPE=Debug -DWITH_MAGICK=true -DWITH_GMP=true -DWITH_HDF5=true -DWITH_CAIRO=true -DWITH_QGLVIEWER=true -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=off"; fi
- if [ $UPLOAD_DOC == "true" ]; then openssl aes-256-cbc -K $encrypted_47769ec71275_key -iv $encrypted_47769ec71275_iv -in .travis/dgtal_rsa.enc -out .travis/dgtal_rsa -d; chmod 600 .travis/dgtal_rsa; BUILD_DOC="true"; fi
- if [ $BUILD_DOC == "true" ]; then wget http://dgtal.org/doc/tags/DGtalTools-tagfile; fi
Expand Down
14 changes: 11 additions & 3 deletions .travis/main_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@ cd build
### Cmake
echo "Using C++ = $CXXCOMPILER"
cmake .. $BTYPE -DCMAKE_CXX_COMPILER=$CXXCOMPILER -DCMAKE_C_COMPILER=$CCOMPILER


make DGtal;
if [ $DEC = "true" ];
then
echo "Compile Dec in non parallel mode to save memory (to fix gcc internal compiler error(Killed))";
make exampleDiscreteExteriorCalculusChladni;
#make exampleDiscreteExteriorCalculusSolve;
#make exampleDECSurface;
make examplePropagation;
make testDiscreteExteriorCalculusExtended;
fi

### DGtal build
make -j 4

Expand All @@ -26,7 +35,6 @@ then
if [ -f io/readers/testMagickReader ]; then
io/readers/testMagickReader
fi

ctest -j 3--output-on-failure


Expand Down
6 changes: 4 additions & 2 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@
- New ImageMagick writer to export images to PNG or JPG formats for
instance. (David Coeurjolly,
[#1304](https://github.com/DGtal-team/DGtal/pull/1304))
- SimpleDistanceColorMap new colormap to easily display distance maps.
- SimpleDistanceColorMap new colormap to easily display distance maps.
(David Coeurjolly, [#1302](https://github.com/DGtal-team/DGtal/pull/1302))
- Fix in MagicReader allowing to load colored images. (David
- Fix in MagicReader allowing to load colored images. (David
Coeurjolly, [#1305](https://github.com/DGtal-team/DGtal/pull/1305))
- Include New ImageMagick writer in GenericWriter. (Bertrand Kerautret,
[#1306](https://github.com/DGtal-team/DGtal/pull/1306))

## Bug Fixes

Expand Down
3 changes: 1 addition & 2 deletions examples/io/viewers/viewer3D-11-extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ struct RandomPointKeyExtension : public Viewer3D<Space, KSpace>::Extension
const Qt::KeyboardModifiers modifiers = event->modifiers();
if ( ( event->key() == Qt::Key_R ) && ( modifiers == Qt::ShiftModifier ) )
{
typedef Viewer::KSpace KSpace;
Point p = viewer.space().lowerBound();
Point q = viewer.space().upperBound();
Point d = q - p;
Expand All @@ -94,7 +93,7 @@ struct RandomPointKeyExtension : public Viewer3D<Space, KSpace>::Extension

// We also override the Viewer3D::helpString method to add a
// description to the viewer.
virtual QString helpString( const Viewer & viewer ) const
virtual QString helpString( const Viewer & /*viewer*/ ) const
{
QString text( "<h2> Random point Viewer3D </h2>" );
text += "Press Shift+R to add points.";
Expand Down
79 changes: 39 additions & 40 deletions examples/shapes/sphereCotangentLaplaceOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,11 @@ using namespace Z3i;
typedef Z3i::Space Space;
typedef Z3i::KSpace KSpace;
typedef Z3i::RealVector RealVector;
typedef Z3i::RealPoint RealPoint;
typedef Z3i::Point Point;
typedef Z3i::RealPoint RealPoint3D;

RealPoint cartesian_to_spherical(const RealPoint & a)
RealPoint cartesian_to_spherical(const RealPoint3D & a)
{
return RealPoint(a.norm(), atan2(a[1], a[0]), acos(a[2]));
return RealPoint3D(a.norm(), atan2(a[1], a[0]), acos(a[2]));
}

struct Options
Expand All @@ -88,8 +87,8 @@ struct Options

template <typename Shape>
void laplacian(Shape& shape, const Options& options,
std::function<double(const RealPoint&)> input_function,
std::function<double(const RealPoint&)> target_function,
std::function<double(const RealPoint3D&)> input_function,
std::function<double(const RealPoint3D&)> target_function,
int argc, char** argv)
{
trace.beginBlock("Laplacian");
Expand Down Expand Up @@ -134,8 +133,8 @@ void laplacian(Shape& shape, const Options& options,

trace.beginBlock( "Making triangulated surface. " );
typedef CanonicCellEmbedder<KSpace> CanonicCellEmbedder;
typedef CanonicCellEmbedder::Value RealPoint;
typedef TriangulatedSurface< RealPoint > TriMesh;
typedef CanonicCellEmbedder::Value RealPoint3D;
typedef TriangulatedSurface< RealPoint3D > TriMesh;
typedef std::map< MyDigitalSurface::Vertex, TriMesh::Index > VertexMap;
TriMesh trimesh;
CanonicCellEmbedder canonicCellembedder(kspace);
Expand Down Expand Up @@ -171,34 +170,34 @@ void laplacian(Shape& shape, const Options& options,
// Iteration over all vertices
for(auto v : vertices)
{
const RealPoint p_i = trimesh.position(v);
const RealPoint3D p_i = trimesh.position(v);
const TriangulatedSurface::ArcRange out_arcs = trimesh.outArcs(v);
double accum = 0.;

// We compute here \Delta f(p_i) by iteration over arcs going out from p_i
for(auto a : out_arcs)
{
// The point p_i -----> p_j
const RealPoint p_j = trimesh.position( trimesh.head(a) );
const RealPoint3D p_j = trimesh.position( trimesh.head(a) );

const TriangulatedSurface::Arc next_left_arc = trimesh.next( a );
const TriangulatedSurface::Arc next_right_arc = trimesh.next( trimesh.opposite(a) );

// Three points of the left triangle
const RealPoint p1 = p_j;
const RealPoint p2 = trimesh.position( trimesh.head( next_left_arc ) );
const RealPoint p3 = p_i;
const RealPoint3D p1 = p_j;
const RealPoint3D p2 = trimesh.position( trimesh.head( next_left_arc ) );
const RealPoint3D p3 = p_i;

// Three points of the right triangle
const RealPoint pp1 = p_j;
const RealPoint pp2 = trimesh.position(trimesh.head( next_right_arc ));
const RealPoint pp3 = p_i;
const RealPoint3D pp1 = p_j;
const RealPoint3D pp2 = trimesh.position(trimesh.head( next_right_arc ));
const RealPoint3D pp3 = p_i;

// Left and right angles
const RealPoint v1 = (p1 - p2) / (p1 - p2).norm();
const RealPoint v2 = (p3 - p2) / (p3 - p2).norm();
const RealPoint vv1 = (pp1 - pp2) / (pp1 - pp2).norm();
const RealPoint vv2 = (pp3 - pp2) / (pp3 - pp2).norm();
const RealPoint3D v1 = (p1 - p2) / (p1 - p2).norm();
const RealPoint3D v2 = (p3 - p2) / (p3 - p2).norm();
const RealPoint3D vv1 = (pp1 - pp2) / (pp1 - pp2).norm();
const RealPoint3D vv2 = (pp3 - pp2) / (pp3 - pp2).norm();

const double alpha = acos( v1.dot(v2) );
const double beta = acos( vv1.dot(vv2) );
Expand All @@ -212,11 +211,11 @@ void laplacian(Shape& shape, const Options& options,
for(auto f : faces_around)
{
const TriangulatedSurface::VertexRange vr = trimesh.verticesAroundFace(f);
RealPoint p = trimesh.position(vr[0]);
RealPoint q = trimesh.position(vr[1]);
RealPoint r = trimesh.position(vr[2]);
RealPoint3D p = trimesh.position(vr[0]);
RealPoint3D q = trimesh.position(vr[1]);
RealPoint3D r = trimesh.position(vr[2]);

const RealPoint cross = (r - p).crossProduct(r - q);
const RealPoint3D cross = (r - p).crossProduct(r - q);
const double faceArea = .5 * cross.norm();

accum_area += faceArea / 3.;
Expand All @@ -228,10 +227,10 @@ void laplacian(Shape& shape, const Options& options,
? laplacian_result(i) = (1 / (2. * accum_area)) * accum
: laplacian_result(i) = .5 * accum;

const RealPoint w_projected = p_i / p_i.norm();
const RealPoint3D w_projected = p_i / p_i.norm();
const double real_laplacian_value = target_function(w_projected);

const RealPoint w_s = cartesian_to_spherical(w_projected);
const RealPoint3D w_s = cartesian_to_spherical(w_projected);

function_out << w_s[1] << " "
<< w_s[2] << " "
Expand Down Expand Up @@ -264,7 +263,7 @@ void laplacian(Shape& shape, const Options& options,
<< " vertices and " << viewmesh.nbFaces() << " faces." << std::endl;

DGtal::ColorBrightnessColorMap<float> colormap_error(error_faces.minCoeff(), error_faces.maxCoeff(), DGtal::Color::Red);
for(int k = 0; k < viewmesh.nbFaces(); k++)
for(unsigned int k = 0; k < viewmesh.nbFaces(); k++)
viewmesh.setFaceColor(k, colormap_error( error_faces(k) ));

QApplication application(argc,argv);
Expand All @@ -288,30 +287,30 @@ int main(int argc, char **argv)
typedef Ball3D<Z3i::Space> Ball;
Ball ball(Point(0.0,0.0,0.0), 1.0);

std::function<double(const RealPoint&)> xx_function = [](const RealPoint& p) {return p[0] * p[0];};
std::function<double(const RealPoint&)> xx_result = [](const RealPoint& p)
std::function<double(const RealPoint3D&)> xx_function = [](const RealPoint3D& p) {return p[0] * p[0];};
std::function<double(const RealPoint3D&)> xx_result = [](const RealPoint3D& p)
{
const RealPoint p_s = cartesian_to_spherical(p);
const RealPoint3D p_s = cartesian_to_spherical(p);
return 2 * cos(p_s[1]) * cos(p_s[1]) * (2 * cos(p_s[2]) * cos(p_s[2]) - sin(p_s[2]) * sin(p_s[2]))
+ 2 * (sin(p_s[1]) * sin(p_s[1]) - cos(p_s[1]) * cos(p_s[1]));
};

std::function<double(const RealPoint&)> cos_function = [](const RealPoint& p) {return p[2];};
std::function<double(const RealPoint&)> cos_result = [](const RealPoint& p)
std::function<double(const RealPoint3D&)> cos_function = [](const RealPoint3D& p) {return p[2];};
std::function<double(const RealPoint3D&)> cos_result = [](const RealPoint3D& p)
{
const RealPoint p_s = cartesian_to_spherical(p);
const RealPoint3D p_s = cartesian_to_spherical(p);
return - 2 * cos(p_s[2]);
};

std::function<double(const RealPoint&)> exp_function = [](const RealPoint& p)
std::function<double(const RealPoint3D&)> exp_function = [](const RealPoint3D& p)
{
const RealPoint p_sphere = p / p.norm();
const RealPoint3D p_sphere = p / p.norm();
return exp(p_sphere[0]);
};
std::function<double(const RealPoint&)> exp_result = [](const RealPoint& p)
std::function<double(const RealPoint3D&)> exp_result = [](const RealPoint3D& p)
{
const RealPoint p_sphere = p / p.norm();
const RealPoint p_s = cartesian_to_spherical(p);
const RealPoint3D p_sphere = p / p.norm();
const RealPoint3D p_s = cartesian_to_spherical(p);

if(p_s[1] == 0 && p_s[2] == 0) return 1.;

Expand All @@ -324,9 +323,9 @@ int main(int argc, char **argv)
return theta_derivative + phi_derivative;
};

std::function<double(const RealPoint&)> input_function
std::function<double(const RealPoint3D&)> input_function
= ( options.function == 0 ) ? xx_function : ( (options.function == 1) ? cos_function : exp_function );
std::function<double(const RealPoint&)> target_function
std::function<double(const RealPoint3D&)> target_function
= ( options.function == 0 ) ? xx_result : ( (options.function == 1) ? cos_result : exp_result );

laplacian<Ball>(ball, options, input_function, target_function, argc, argv);
Expand Down
2 changes: 1 addition & 1 deletion src/DGtal/io/readers/LongvolReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ namespace DGtal
{
aValue = 0;
char c;
for (auto size = 0; size < sizeof( Word ); ++size)
for (unsigned int size = 0; size < sizeof( Word ); ++size)
{
fin.get( c ) ;
unsigned char cc=static_cast<unsigned char>(c);
Expand Down
2 changes: 2 additions & 0 deletions src/DGtal/io/viewers/Viewer3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ namespace DGtal
/// The associated viewer.
typedef Viewer3D<Space, KSpace> Viewer;

virtual ~Extension() = default;

/// This method may be overloaded to capture other key
/// events. It will be called at the beginning of Viewer3D::keyPressEvent.
///
Expand Down
27 changes: 27 additions & 0 deletions src/DGtal/io/writers/GenericWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,33 @@ namespace DGtal

};


/**
* GenericWriter
* Template partial specialisation for images of dimension 2 with image value DGtal::Color
**/
template <typename TContainer, typename TFunctor>
struct GenericWriter<TContainer, 2, DGtal::Color, TFunctor>
{
BOOST_CONCEPT_ASSERT(( concepts::CConstImage<TContainer> )) ;

/**
* Export the 2D image file.
* @param filename the filename of the saved image (with a extension name).
* @param anImage the image to be saved.
* @param aFunctor to apply image transformation before saving.
*
**/

static bool exportFile(const std::string &filename,
const TContainer &anImage,
const TFunctor & aFunctor = TFunctor() );

};




/**
* GenericWriter
* Template partial specialisation for images of dimension 2 and Functor returning a Color object
Expand Down
42 changes: 42 additions & 0 deletions src/DGtal/io/writers/GenericWriter.ih
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
#include "DGtal/io/writers/PPMWriter.h"
#include "DGtal/io/writers/PGMWriter.h"
#include "DGtal/io/writers/RawWriter.h"
#ifdef WITH_MAGICK
#include "DGtal/io/writers/MagickWriter.h"
#endif



Expand Down Expand Up @@ -215,6 +218,38 @@ exportFile( const std::string & filename,
return false;
}



template <typename TContainer, typename TFunctor>
inline
bool
DGtal::GenericWriter<TContainer, 2, DGtal::Color, TFunctor>::
exportFile( const std::string & filename,
const TContainer & anImage,
const TFunctor & aFunctor
)
{
DGtal::IOException dgtalio;
const std::string extension = filename.substr( filename.find_last_of(".") + 1 );
if ( extension == "ppm" )
{
return PPMWriter< TContainer, TFunctor >::exportPPM( filename, anImage, aFunctor );
}
#ifdef WITH_MAGICK
else if ( extension == "gif" || extension == "jpg" || extension == "bmp" || extension == "png" )
{
return MagickWriter< TContainer, TFunctor >::exportMagick( filename, anImage, aFunctor );
}
#endif
else
{
trace.error() << "Extension " << extension<< " in 2D, not yet implemented in DGtal GenericWriter." << std::endl;
throw dgtalio;
}

return false;
}

template <typename TContainer, typename TValue>
inline
bool
Expand All @@ -230,6 +265,13 @@ exportFile( const std::string & filename,
{
return PPMWriter<TContainer, DGtal::HueShadeColorMap<TValue> >::exportPPM( filename, anImage, aFunctor );
}
#ifdef WITH_MAGICK
else if ( extension == "gif" || extension == "jpg" || extension == "bmp" || extension == "png" )
{
return MagickWriter< TContainer, DGtal::HueShadeColorMap<TValue> >::exportMagick( filename, anImage, aFunctor );
}
#endif

else if ( extension == "raw" )
{
return RawWriter< TContainer, DGtal::HueShadeColorMap<TValue> >::template exportRaw<DGtal::Color>( filename, anImage, aFunctor );
Expand Down
Loading