33 #if defined(DECImageHelpers_RECURSES)
34 #error Recursive header files inclusion detected in DECImageHelpers.h
37 #define DECImageHelpers_RECURSES
39 #if !defined DECImageHelpers_h
41 #define DECImageHelpers_h
46 #include "DGtal/base/Common.h"
47 #include "DGtal/images/CImage.h"
48 #include "DGtal/topology/CCellularGridSpaceND.h"
49 #include "DGtal/math/linalg/CLinearAlgebra.h"
50 #include "DGtal/dec/DiscreteExteriorCalculus.h"
70 template <
typename Calculus, DGtal::Dimension dim, DGtal::Duality duality>
71 DGtal::LinearOperator<Calculus, dim, duality, dim, duality>
72 diagonal(
const DGtal::KForm<Calculus, dim, duality>& kform)
74 typedef DGtal::LinearOperator<Calculus,dim, duality, dim, duality> Operator;
75 typedef typename Calculus::LinearAlgebraBackend::Triplet Triplet;
76 typedef typename Calculus::Index Index;
77 typedef std::vector<Triplet> Triplets;
80 for (Index index=0; index<kform.length(); index++)
81 triplets.push_back(Triplet(index, index, kform.myContainer(index)));
83 Operator op( kform.myCalculus );
84 op.myContainer.setFromTriplets( triplets.begin(), triplets.end() );
97 template <
typename Calculus, DGtal::Dimension dim, DGtal::Duality duality>
99 squares(DGtal::KForm<Calculus, dim, duality>& kform)
101 kform.myContainer.array() = kform.myContainer.array().square();
116 template <
typename Calculus, DGtal::Dimension dim, DGtal::Duality duality>
117 DGtal::LinearOperator<Calculus, dim, duality, dim, duality>
137 template <
typename Image>
138 void writePixel( Image& image,
typename Image::Point pt,
typename Image::Value val,
141 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
142 typedef typename Image::Point Point;
143 typedef typename Point::Coordinate Coordinate;
145 for (
int y = 0; y < pixel_size; y++ )
146 for (
int x = 0; x < pixel_size; x++ )
148 Point q( (Coordinate) x, (Coordinate) y );
149 image.setValue( pt + q, val );
165 template <
typename Image>
169 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
170 typedef typename Image::Point Point;
171 typedef typename Point::Coordinate Coordinate;
172 int pixel_size_x = NumberTraits<Coordinate>::even( pt[ 0 ] ) ? 1 : pixel_size;
173 int pixel_size_y = NumberTraits<Coordinate>::even( pt[ 1 ] ) ? 1 : pixel_size;
176 for (
int y = 0; y < pixel_size_y; y++ )
177 for (
int x = 0; x < pixel_size_x; x++ )
179 Point q( (Coordinate) x, (Coordinate) y );
180 image.setValue( pt + q, val );
196 template <
typename Image>
197 void writeDualLinel( Image& image,
typename Image::Point pt,
typename Image::Value val,
200 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
201 typedef typename Image::Point Point;
202 typedef typename Point::Coordinate Coordinate;
203 int pixel_size_x = NumberTraits<Coordinate>::even( pt[ 0 ] ) ? 0 : pixel_size-1;
204 int pixel_size_y = NumberTraits<Coordinate>::even( pt[ 1 ] ) ? 0 : pixel_size-1;
207 for (
int y = pixel_size_y; y < pixel_size; y++ )
208 for (
int x = pixel_size_x; x < pixel_size; x++ )
210 Point q( (Coordinate) x, (Coordinate) y );
211 image.setValue( pt + q, val );
236 template <
typename Calculus,
typename AnyForm2,
typename Image,
typename Function>
238 (
const Calculus& calculus,
241 const Function& functor,
242 double cut_low = 0.0,
double cut_up = 1.0,
int pixel_size = 1 )
244 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
245 typedef typename Calculus::Index Index;
246 typedef typename Calculus::SCell SCell;
247 typedef typename Calculus::Scalar Scalar;
248 typedef typename Calculus::KSpace KSpace;
249 typedef typename KSpace::Point Point;
250 typedef typename KSpace::Integer Integer;
251 double min_u = NumberTraits<Scalar>::castToDouble( u.myContainer[ 0 ] );
252 double max_u = min_u;
253 for ( Index index = 0; index < u.myContainer.rows(); index++)
255 double v = NumberTraits<Scalar>::castToDouble( u.myContainer[ index ] );
256 min_u = std::min( min_u, v );
257 max_u = std::max( max_u, v );
259 if ( min_u < cut_low ) min_u = cut_low;
260 if ( max_u > cut_up ) max_u = cut_up;
261 for ( Index index = 0; index < u.myContainer.rows(); index++)
263 SCell cell = u.getSCell( index );
264 double v = NumberTraits<Scalar>::castToDouble( u.myContainer[ index ] );
265 double w = std::min( cut_up, std::max( cut_low, v ) );
266 if ( min_u != max_u ) w = ( w - min_u ) / ( max_u - min_u );
267 writePixel( image, calculus.myKSpace.sCoords( cell ), functor( w ), pixel_size );
296 template <
typename Calculus,
typename Form1,
typename Image,
typename Function,
typename Predicate>
298 (
const Calculus& calculus,
299 const Form1& v,
bool primal,
301 const Function& functor,
302 const Predicate& predicate,
303 double cut_low = 0.0,
double cut_up = 1.0,
int pixel_size = 1 )
305 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
306 typedef typename Calculus::Index Index;
307 typedef typename Calculus::SCell SCell;
308 typedef typename Calculus::Scalar Scalar;
309 typedef typename Calculus::KSpace KSpace;
310 typedef typename KSpace::Point Point;
311 typedef typename KSpace::Integer Integer;
312 double min_v = NumberTraits<Scalar>::castToDouble( v.myContainer[ 0 ] );
313 double max_v = min_v;
314 for ( Index index = 0; index < v.myContainer.rows(); index++)
316 double w = NumberTraits<Scalar>::castToDouble( v.myContainer[ index ] );
317 min_v = std::min( min_v, w );
318 max_v = std::max( max_v, w );
320 if ( min_v < cut_low ) min_v = cut_low;
321 if ( max_v > cut_up ) max_v = cut_up;
322 for ( Index index = 0; index < v.myContainer.rows(); index++)
324 SCell cell = v.getSCell( index );
325 double u = NumberTraits<Scalar>::castToDouble( v.myContainer[ index ] );
326 if ( ! predicate( u ) )
continue;
327 double w = std::min( cut_up, std::max( cut_low, u ) );
328 if ( min_v != max_v ) w = ( w - min_v ) / ( max_v - min_v );
329 Point kpt = calculus.myKSpace.sKCoords( cell );
358 template <
typename Calculus,
typename Image,
typename Function,
typename Predicate>
360 (
const Calculus& calculus,
361 const typename Calculus::DualForm1& v,
363 const Function& functor,
364 const Predicate& predicate,
365 double cut_low = 0.0,
double cut_up = 1.0,
int pixel_size = 1 )
367 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
368 form1ToImage( calculus, v,
false, image, functor, predicate,
369 cut_low, cut_up, pixel_size );
395 template <
typename Calculus,
typename Image,
typename Function,
typename Predicate>
397 (
const Calculus& calculus,
398 const typename Calculus::PrimalForm1& v,
400 const Function& functor,
401 const Predicate& predicate,
402 double cut_low = 0.0,
double cut_up = 1.0,
int pixel_size = 1 )
404 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
405 form1ToImage( calculus, v,
true, image, functor, predicate,
406 cut_low, cut_up, pixel_size );
432 template <
typename Calculus,
typename AnyForm2,
typename Image,
typename Function>
434 (
const Calculus& calculus,
439 const Function& functor,
440 double cut_low = 0.0,
double cut_up = 1.0,
int pixel_size = 1 )
442 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
443 typedef typename Calculus::Index Index;
444 typedef typename Calculus::SCell SCell;
445 typedef typename Calculus::Scalar Scalar;
446 double min_u = NumberTraits<Scalar>::castToDouble( u0.myContainer[ 0 ] );
447 double max_u = min_u;
448 for ( Index index = 0; index < u0.myContainer.rows(); index++)
450 double v = NumberTraits<Scalar>::castToDouble( u0.myContainer[ index ] );
451 min_u = std::min( min_u, v );
452 max_u = std::max( max_u, v );
454 for ( Index index = 0; index < u1.myContainer.rows(); index++)
456 double v = NumberTraits<Scalar>::castToDouble( u1.myContainer[ index ] );
457 min_u = std::min( min_u, v );
458 max_u = std::max( max_u, v );
460 for ( Index index = 0; index < u2.myContainer.rows(); index++)
462 double v = NumberTraits<Scalar>::castToDouble( u2.myContainer[ index ] );
463 min_u = std::min( min_u, v );
464 max_u = std::max( max_u, v );
466 if ( min_u < cut_low ) min_u = cut_low;
467 if ( max_u > cut_up ) max_u = cut_up;
468 for ( Index index = 0; index < u0.myContainer.rows(); index++)
470 SCell cell = u0.getSCell( index );
471 double v0 = NumberTraits<Scalar>::castToDouble( u0.myContainer[ index ] );
472 double w0 = std::min( cut_up, std::max( cut_low, v0 ) );
473 if ( min_u != max_u ) w0 = ( w0 - min_u ) / ( max_u - min_u );
474 double v1 = NumberTraits<Scalar>::castToDouble( u1.myContainer[ index ] );
475 double w1 = std::min( cut_up, std::max( cut_low, v1 ) );
476 if ( min_u != max_u ) w1 = ( w1 - min_u ) / ( max_u - min_u );
477 double v2 = NumberTraits<Scalar>::castToDouble( u2.myContainer[ index ] );
478 double w2 = std::min( cut_up, std::max( cut_low, v2 ) );
479 if ( min_u != max_u ) w2 = ( w2 - min_u ) / ( max_u - min_u );
480 writePixel( image, calculus.myKSpace.sCoords( cell ), functor( w0, w1, w2 ), pixel_size );
504 template <
typename Calculus,
typename AnyForm2,
typename Image>
506 (
const Calculus& calculus,
509 double cut_low = 0.0,
double cut_up = 1.0,
512 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
514 [] (
double x ) {
return (
unsigned char) ( round( x * 255.0 ) ); },
515 cut_low, cut_up, pixel_size );
538 template <
typename Calculus,
typename Image>
540 (
const Calculus& calculus,
541 const typename Calculus::PrimalForm1& v,
543 double cut_low = 0.0,
double cut_up = 1.0,
546 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
551 [] (
double x ) {
return (
unsigned char) ( round( x * 255.0 ) ); },
552 [] (
double x ) {
return x < 0.25; },
553 cut_low, cut_up, pixel_size );
576 template <
typename Calculus,
typename Image>
578 (
const Calculus& calculus,
579 const typename Calculus::DualForm1& v,
581 double cut_low = 0.0,
double cut_up = 1.0,
584 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
589 [] (
double x ) {
return (
unsigned char) ( round( x * 255.0 ) ); },
590 [] (
double x ) {
return x < 0.25; },
591 cut_low, cut_up, pixel_size );
615 template <
typename Calculus,
typename Image>
617 (
const Calculus& calculus,
618 const typename Calculus::PrimalForm1& v,
619 Image& image, Color color,
620 double cut_low = 0.0,
double cut_up = 1.0,
623 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
628 [color] (
double x ) {
return color; },
629 [] (
double x ) {
return x < 0.25; },
630 cut_low, cut_up, pixel_size );
654 template <
typename Calculus,
typename Image>
656 (
const Calculus& calculus,
657 const typename Calculus::DualForm1& v,
658 Image& image, Color color,
659 double cut_low = 0.0,
double cut_up = 1.0,
662 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
667 [color] (
double x ) {
return color; },
668 [] (
double x ) {
return x < 0.25; },
669 cut_low, cut_up, pixel_size );
697 template <
typename Calculus,
typename AnyForm2,
typename Image>
699 (
const Calculus& calculus,
704 double cut_low = 0.0,
double cut_up = 1.0,
707 BOOST_CONCEPT_ASSERT(( concepts::CImage<Image> ));
709 ( calculus, u0, u1, u2, image,
710 [] (
double r,
double g,
double b )
711 {
return Color( (
unsigned char) ( round( r * 255.0 ) ),
712 (
unsigned char) ( round( g * 255.0 ) ),
713 (
unsigned char) ( round( b * 255.0 ) ) ); },
714 cut_low, cut_up, pixel_size );
739 template <
typename TKSpace,
740 typename TLinearAlgebra = EigenLinearAlgebraBackend >
745 typedef typename KSpace::Space
Space;
746 typedef typename Space::Point
Point;
748 typedef typename RealVector::Component
Scalar;
749 typedef typename KSpace::SCell
SCell;
750 typedef typename KSpace::Cell
Cell;
753 typedef DiscreteExteriorCalculus<2,2, LinearAlgebra>
Calculus;
755 typedef typename Calculus::Index
Index;
777 typedef DiscreteExteriorCalculusSolver<Calculus, LinearAlgebraSolver, 0, PRIMAL, 0, PRIMAL>
779 typedef DiscreteExteriorCalculusSolver<Calculus, LinearAlgebraSolver, 1, PRIMAL, 1, PRIMAL>
812 void init( Clone<KSpace> aKSpace )
817 Point p0 = K.uKCoords( K.lowerCell() );
818 Point p1 = K.uKCoords( K.upperCell() );
821 if (
verbose > 0 ) trace.beginBlock(
"building AT functionnals");
825 calculus.insertSCell( K.sCell( *it ) );
829 if (
verbose > 1 ) trace.info() <<
"primal_D0" << std::endl;
830 D0 =
calculus.template derivative<0,PRIMAL>();
831 if (
verbose > 1 ) trace.info() <<
"primal_D1" << std::endl;
832 D1 =
calculus.template derivative<1,PRIMAL>();
833 if (
verbose > 1 ) trace.info() <<
"dual_D0" << std::endl;
835 if (
verbose > 1 ) trace.info() <<
"dual_D1" << std::endl;
837 if (
verbose > 1 ) trace.info() <<
"primal_h1" << std::endl;
839 if (
verbose > 1 ) trace.info() <<
"primal_h1" << std::endl;
841 if (
verbose > 1 ) trace.info() <<
"primal_h2" << std::endl;
843 if (
verbose > 1 ) trace.info() <<
"dual_h1" << std::endl;
845 if (
verbose > 1 ) trace.info() <<
"dual_h1" << std::endl;
847 if (
verbose > 1 ) trace.info() <<
"dual_h2" << std::endl;
849 if (
verbose > 0 ) trace.endBlock();
922 #undef DECImageHelpers_RECURSES
void primalForm1ToGreyLevelImage(const Calculus &calculus, const typename Calculus::PrimalForm1 &v, Image &image, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
void form2ToImage(const Calculus &calculus, const AnyForm2 &u, Image &image, const Function &functor, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
void primalForm1ToImage(const Calculus &calculus, const typename Calculus::PrimalForm1 &v, Image &image, const Function &functor, const Predicate &predicate, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
void dualForm1ToGreyLevelImage(const Calculus &calculus, const typename Calculus::DualForm1 &v, Image &image, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
void writePrimalLinel(Image &image, typename Image::Point pt, typename Image::Value val, int pixel_size=1)
void form1ToImage(const Calculus &calculus, const Form1 &v, bool primal, Image &image, const Function &functor, const Predicate &predicate, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
void form2ToGreyLevelImage(const Calculus &calculus, const AnyForm2 &u, Image &image, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
void dualForm1ToRGBColorImage(const Calculus &calculus, const typename Calculus::DualForm1 &v, Image &image, Color color, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
DGtal::LinearOperator< Calculus, dim, duality, dim, duality > squaredDiagonal(const DGtal::KForm< Calculus, dim, duality > &kform)
void dualForm1ToImage(const Calculus &calculus, const typename Calculus::DualForm1 &v, Image &image, const Function &functor, const Predicate &predicate, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
void writePixel(Image &image, typename Image::Point pt, typename Image::Value val, int pixel_size=1)
void threeForms2ToRGBColorImage(const Calculus &calculus, const AnyForm2 &u0, const AnyForm2 &u1, const AnyForm2 &u2, Image &image, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
void writeDualLinel(Image &image, typename Image::Point pt, typename Image::Value val, int pixel_size=1)
void primalForm1ToRGBColorImage(const Calculus &calculus, const typename Calculus::PrimalForm1 &v, Image &image, Color color, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
DGtal::LinearOperator< Calculus, dim, duality, dim, duality > diagonal(const DGtal::KForm< Calculus, dim, duality > &kform)
void threeForms2ToImage(const Calculus &calculus, const AnyForm2 &u0, const AnyForm2 &u1, const AnyForm2 &u2, Image &image, const Function &functor, double cut_low=0.0, double cut_up=1.0, int pixel_size=1)
void squares(DGtal::KForm< Calculus, dim, duality > &kform)
Aim: This class simplifies the development of 2D image processing tools using discrete exterior calcu...
Calculus::DualAntiderivative1 DualAntiderivative1
DECImage2D & operator=(const DECImage2D &other)=delete
int verbose
The verbose level (0: silent).
DualDerivative0 dual_D0
dual derivative dual 0-form -> dual 1-form
Calculus::DualDerivative0 DualDerivative0
Calculus::PrimalHodge2 PrimalHodge2
DECImage2D(int _verbose=1)
PrimalHodge2 primal_h2
hodge star: 2-form -> dual 2-form
PrimalDerivative0 D0
primal derivative: 0-form -> 1-form
Calculus calculus
The discrete exterior calculus instance.
DualHodge0 dual_h0
hodge star: dual 0-form -> 0-form
Calculus::PrimalForm1 PrimalForm1
DiscreteExteriorCalculusSolver< Calculus, LinearAlgebraSolver, 1, PRIMAL, 1, PRIMAL > SolverV
Calculus::DualHodge2 DualHodge2
Calculus::PrimalAntiderivative1 PrimalAntiderivative1
DualHodge1 dual_h1
hodge star: dual 1-form -> 1-form
BOOST_CONCEPT_ASSERT((concepts::CCellularGridSpaceND< KSpace >))
HyperRectDomain< Space > Domain
TLinearAlgebra LinearAlgebra
Calculus::PrimalDerivative0 PrimalDerivative0
Calculus::PrimalForm0 PrimalForm0
RealVector::Component Scalar
Calculus::PrimalForm2 PrimalForm2
Calculus::PrimalDerivative1 PrimalDerivative1
DualHodge2 dual_h2
hodge star: dual 2-form -> 2-form
DiscreteExteriorCalculusSolver< Calculus, LinearAlgebraSolver, 0, PRIMAL, 0, PRIMAL > SolverU
PrimalHodge0 primal_h0
hodge star: 0-form -> dual 0-form
DiscreteExteriorCalculusFactory< LinearAlgebra > CalculusFactory
Calculus::PrimalIdentity0 PrimalIdentity0
PrimalHodge1 primal_h1
hodge star: 1-form -> dual 1-form
Space::RealVector RealVector
Calculus::DualAntiderivative2 DualAntiderivative2
void init(Clone< KSpace > aKSpace)
Calculus::DualHodge1 DualHodge1
DiscreteExteriorCalculus< 2, 2, LinearAlgebra > Calculus
BOOST_STATIC_ASSERT((KSpace::dimension==2))
Calculus::PrimalHodge1 PrimalHodge1
Calculus::PrimalIdentity2 PrimalIdentity2
Domain cell_domain
The cell domain (i.e. all the cells)
Calculus::PrimalIdentity1 PrimalIdentity1
LinearAlgebra::SolverSimplicialLLT LinearAlgebraSolver
Calculus::PrimalHodge0 PrimalHodge0
DECImage2D(DECImage2D &&other)=delete
DECImage2D(const DECImage2D &other)=delete
Calculus::DualHodge0 DualHodge0
Calculus::PrimalAntiderivative2 PrimalAntiderivative2
PrimalDerivative1 D1
primal derivative: 1-form -> 2-form
Calculus::DualDerivative1 DualDerivative1
Domain domain
The image domain (i.e. all the pixels)
DualDerivative1 dual_D1
dual derivative dual 1-form -> dual 2-form