aimsalgo  5.1.2
Neuroimaging image processing
ffd.h
Go to the documentation of this file.
1 /* Copyright (C) 2000-2013 CEA
2  *
3  * This software and supporting documentation were developed by
4  * bioPICSEL
5  * CEA/DSV/I²BM/MIRCen/LMN, Batiment 61,
6  * 18, route du Panorama
7  * 92265 Fontenay-aux-Roses
8  * France
9  */
10 
11 
12 #ifndef AIMS_REGISTRATION_FFD_H
13 #define AIMS_REGISTRATION_FFD_H
14 
15 #include <cartodata/volume/volume.h> // Volume
16 #include <aims/io/writer.h> // aims::Reader / Writer
17 #include <aims/math/bspline.h> // aims::TabulBSpline
19 #include <soma-io/transformation/transformation.h> // soma::Transformation
20 
21 class Graph;
22 
23 namespace aims {
24 
25 //==========================================================================
26  // FFD TRANSFORMATION
27  //==========================================================================
28 
38  {
39  public:
40  FfdTransformation( int dimX = 0, int dimY = 1, int dimZ = 1,
41  float sizeX = 1., float sizeY = 1., float sizeZ = 1. );
42  template <typename T>
43  FfdTransformation( int dimX, int dimY, int dimZ,
44  const carto::rc_ptr<carto::Volume<T> > & test_volume );
45  template <typename T>
46  FfdTransformation( int dimX, int dimY, int dimZ,
47  const carto::Volume<T> & test_volume );
48 
52 
53  operator const carto::VolumeRef<Point3df> & () const
54  { return _ctrlPointDelta; }
56  { return _ctrlPointDelta; }
57  operator const carto::rc_ptr<carto::Volume<Point3df> > & () const
58  { return _ctrlPointDelta; }
60  { return _ctrlPointDelta; }
62  { return _ctrlPointDelta; }
63 
65  bool isIdentity() const CARTO_OVERRIDE { return false; }
66 
67  //--- Control Knots ------------------------------------------------------
68  Point3df getCtrlKnot( int nx, int ny, int nz ) const;
69  void updateCtrlKnot( int nx, int ny, int nz, const Point3df & newCtrlKnot );
71  const carto::rc_ptr<carto::Volume<Point3df> > & newCtrlKnotGrid );
73  const carto::rc_ptr<carto::Volume<Point3df> > & newDeformationGrid );
74 
75  //--- Modify -------------------------------------------------------------
76  void increaseResolution( const Point3d & addKnots );
77  // void inverseTransform();
78  // void estimateLocalDisplacement( const Point3df & voxelSize);
79 
80  //--- Deformation --------------------------------------------------------
81  Point3dd deformation( const Point3dd& p_mm ) const;
82  Point3dd ffdCoord( const Point3dd& p_mm ) const
83  { return mmToSplineVox(p_mm); }
84 
85  //--- Parameters ---------------------------------------------------------
86  int dimX() const { return _dimx; }
87  int dimY() const { return _dimy; }
88  int dimZ() const { return _dimz; }
89  int getSizeX() const { return _dimx; }
90  int getSizeY() const { return _dimy; }
91  int getSizeZ() const { return _dimz; }
92  std::vector<int> getSize() const
93  { std::vector<int> s( 3 ); s[0] = _dimx; s[1] = _dimy; s[2] = _dimz;
94  return s; }
95  float sizeX() const { return _vsx; }
96  float sizeY() const { return _vsy; }
97  float sizeZ() const { return _vsz; }
98  std::vector<float> getVoxelSize() const
99  { std::vector<float> v( 3 ); v[0] = _vsx; v[1] = _vsy; v[2] = _vsz;
100  return v; }
101  bool isFlat( int i ) const
102  {
103  switch(i)
104  {
105  case 0: return _flatx;
106  case 1: return _flaty;
107  case 2: return _flatz;
108  default: return false;
109  }
110  }
111  bool isXFlat() const { return _flatx; }
112  bool isYFlat() const { return _flaty; }
113  bool isZFlat() const { return _flatz; }
114  virtual void updateDimensions();
115 
116  //--- Debug --------------------------------------------------------------
118  void writeDebugCtrlKnots( const std::string & filename ) const;
119  void writeDebugDeformations( const std::string & filename,
120  int dimX, int dimY, int dimZ,
121  float sizeX, float sizeY, float sizeZ ) const;
122 
123  //--- Output -------------------------------------------------------------
124  void write( const std::string & filename ) const;
125 
126  protected:
127  //--- Protected methods --------------------------------------------------
128  Point3dd splineVoxToMm( const Point3dd& p ) const;
129  Point3dd mmToSplineVox( const Point3dd& p ) const;
131  const carto::rc_ptr<carto::Volume<Point3df> > & newGrid );
132 
133  virtual Point3dd _deformation( const Point3dd& p_mm ) const = 0;
134 
137  float _vsx, _vsy, _vsz;
139  };
140 
141  template <typename T>
142  inline
144  int dimX, int dimY, int dimZ,
145  const carto::rc_ptr<carto::Volume<T> > & test_volume ):
146  _ctrlPointDelta( dimX, dimY, dimZ ),
147  _dimx( dimX ), _dimy( dimY ), _dimz( dimZ ),
148  _flatx( dimX == 1 ), _flaty( dimY == 1 ), _flatz( dimZ == 1 )
149  {
150  _ctrlPointDelta = Point3df(0., 0., 0.);
151  _ctrlPointDelta.setVoxelSize(
152  _flatx ? test_volume->getVoxelSize()[0] : double(test_volume->getSizeX() - 1) / double(dimX - 1) * test_volume->getVoxelSize()[0],
153  _flaty ? test_volume->getVoxelSize()[1] : double(test_volume->getSizeY() - 1) / double(dimY - 1) * test_volume->getVoxelSize()[1],
154  _flatz ? test_volume->getVoxelSize()[2] : double(test_volume->getSizeZ() - 1) / double(dimZ - 1) * test_volume->getSizeZ()
155  );
157  }
158 
159  template <typename T>
160  inline
161  FfdTransformation::FfdTransformation( int dimX, int dimY, int dimZ,
162  const carto::Volume<T> & test_volume ):
163  _ctrlPointDelta( dimX, dimY, dimZ ),
164  _dimx( dimX ), _dimy( dimY ), _dimz( dimZ ),
165  _flatx( dimX == 1 ), _flaty( dimY == 1 ), _flatz( dimZ == 1 )
166  {
167  _ctrlPointDelta = Point3df(0., 0., 0.);
168  std::vector<float> vs = test_volume.getVoxelSize();
169  _ctrlPointDelta.setVoxelSize(
170  _flatx ? vs[0] : double(test_volume.getSizeX() - 1) / double(dimX - 1) * vs[0],
171  _flaty ? vs[1] : double(test_volume.getSizeY() - 1) / double(dimY - 1) * vs[1],
172  _flatz ? vs[2] : double(test_volume.getSizeZ() - 1) / double(dimZ - 1) * vs[2]
173  );
175  }
176 
177  inline Point3dd
179  {
180  return Point3dd( p[0] * sizeX(),
181  p[1] * sizeY(),
182  p[2] * sizeZ() );
183  }
184 
185  inline Point3dd
187  {
188  return Point3dd( p[0] / sizeX(),
189  p[1] / sizeY(),
190  p[2] / sizeZ() );
191  }
192 
193  //==========================================================================
194  // FFD TRANSFORMATION
195  //==========================================================================
196 
225  {
226  public:
227  //--- Constructor --------------------------------------------------------
228  SplineFfd( int dimX = 0, int dimY = 1, int dimZ = 1,
229  float sizeX = 1., float sizeY = 1., float sizeZ = 1. );
230  template <typename T>
231  SplineFfd( int dimX, int dimY, int dimZ,
232  const carto::rc_ptr<carto::Volume<T> > & test_volume );
233  template <typename T>
234  SplineFfd( int dimX, int dimY, int dimZ,
235  const carto::Volume<T> & test_volume );
236 
237  SplineFfd( const SplineFfd & other );
239  SplineFfd & operator=( const SplineFfd & other );
240 
241  virtual void updateDimensions();
242  //--- Deformation --------------------------------------------------------
243  Point3dd deformation( const Point3dd& p_mm ) const;
244  double spline3( double x ) const { return _spline(x); }
245 
246  private:
247  virtual Point3dd transformDouble( double x, double y, double z ) const;
248  virtual Point3dd _deformation( const Point3dd& p_mm ) const
249  { return deformation_private(p_mm); };
250  Point3dd deformation_private( const Point3dd& p_mm ) const;
251 
252  const aims::TabulBSpline _spline;
253  std::vector<int> _mirrorcoefvecx;
254  std::vector<int> _mirrorcoefvecy;
255  std::vector<int> _mirrorcoefvecz;
256  int *_mirrorcoefx;
257  int *_mirrorcoefy;
258  int *_mirrorcoefz;
259  };
260 
261  template <typename T>
262  inline
263  SplineFfd::SplineFfd( int dimX, int dimY, int dimZ,
264  const carto::rc_ptr<carto::Volume<T> > & test_volume ):
265  FfdTransformation( dimX, dimY, dimZ, test_volume ),
266  _spline(3, 0)
267  {
268  }
269 
270  template <typename T>
271  inline
272  SplineFfd::SplineFfd( int dimX, int dimY, int dimZ,
273  const carto::Volume<T> & test_volume ):
274  FfdTransformation( dimX, dimY, dimZ, test_volume ),
275  _spline(3, 0)
276  {
277  }
278 
279 
280  //==========================================================================
281  // FFD TRILINEAR RESAMPLED TRANSFORMATION
282  //==========================================================================
283 
294  {
295  public:
296  //--- Constructor --------------------------------------------------------
297  TrilinearFfd( int dimX = 0, int dimY = 1, int dimZ = 1,
298  float sizeX = 1., float sizeY = 1., float sizeZ = 1. );
299  template <typename T>
300  TrilinearFfd( int dimX, int dimY, int dimZ,
301  const carto::rc_ptr<carto::Volume<T> > & test_volume );
302 
303  TrilinearFfd( const TrilinearFfd & other );
305  TrilinearFfd & operator=( const TrilinearFfd & other );
306 
307  //--- Deformation --------------------------------------------------------
308  Point3dd deformation( const Point3dd& p_mm ) const;
309  private:
310  virtual Point3dd transformDouble( double x, double y, double z ) const;
311  virtual Point3dd _deformation( const Point3dd& p_mm ) const
312  { return deformation_private(p_mm); };
313  Point3dd deformation_private( const Point3dd& p_mm ) const;
314  };
315 
316  template <typename T>
317  inline
319  int dimX, int dimY, int dimZ,
320  const carto::rc_ptr<carto::Volume<T> > & test_volume ):
321  FfdTransformation( dimX, dimY, dimZ, test_volume )
322  {
323  }
324 
325 //============================================================================
326 // FFD READER/WRITER
327 //============================================================================
328 
332  template<>
334  : public Writer<carto::Volume<Point3df> >
335  {
337  public:
338  inline Writer(): base() {}
339  inline Writer( const std::string& filename,
341  base( filename, options ) {}
342  virtual ~Writer() {}
343  virtual bool write( const aims::FfdTransformation & obj,
344  bool ascii = false,
345  const std::string* format = 0 );
346  };
347 
348 } // namespace aims
349 
350 
351 // ---
352 
353 namespace soma
354 {
355 
356  template <> inline std::string
357  DataTypeCode<aims::FfdTransformation>::objectType()
358  {
359  return "FFDTransformation";
360  }
361 
362  template <> inline std::string
363  DataTypeCode<aims::FfdTransformation>::dataType()
364  {
365  return "VOID";
366  }
367 
368  template <> inline std::string
369  DataTypeCode<aims::FfdTransformation>::name()
370  {
371  return "FFDTransformation";
372  }
373 
374 }
375 
376 
377 #endif
FFD vector field deformation transform.
Definition: ffd.h:38
std::vector< int > getSize() const
Definition: ffd.h:92
float sizeY() const
Definition: ffd.h:96
void updateGridResolution(const carto::rc_ptr< carto::Volume< Point3df > > &newGrid)
void updateAllCtrlKnot(const carto::rc_ptr< carto::Volume< Point3df > > &newCtrlKnotGrid)
virtual Point3dd _deformation(const Point3dd &p_mm) const =0
void increaseResolution(const Point3d &addKnots)
Point3dd deformation(const Point3dd &p_mm) const
carto::VolumeRef< Point3df > _ctrlPointDelta
Definition: ffd.h:135
int getSizeZ() const
Definition: ffd.h:91
void printControlPointsGrid() const
void write(const std::string &filename) const
FfdTransformation(int dimX=0, int dimY=1, int dimZ=1, float sizeX=1., float sizeY=1., float sizeZ=1.)
bool isXFlat() const
Definition: ffd.h:111
int getSizeX() const
Definition: ffd.h:89
Point3dd splineVoxToMm(const Point3dd &p) const
Definition: ffd.h:178
FfdTransformation & operator=(const FfdTransformation &other)
std::vector< float > getVoxelSize() const
Definition: ffd.h:98
int dimX() const
Definition: ffd.h:86
FfdTransformation(const carto::rc_ptr< carto::Volume< Point3df > > &other)
Point3df getCtrlKnot(int nx, int ny, int nz) const
int dimY() const
Definition: ffd.h:87
bool isZFlat() const
Definition: ffd.h:113
virtual void updateDimensions()
bool isYFlat() const
Definition: ffd.h:112
void writeDebugCtrlKnots(const std::string &filename) const
bool isFlat(int i) const
Definition: ffd.h:101
void writeDebugDeformations(const std::string &filename, int dimX, int dimY, int dimZ, float sizeX, float sizeY, float sizeZ) const
void updateAllCtrlKnotFromDeformation(const carto::rc_ptr< carto::Volume< Point3df > > &newDeformationGrid)
bool isIdentity() const CARTO_OVERRIDE
Always false, because testing for identity is expensive.
Definition: ffd.h:65
float sizeX() const
Definition: ffd.h:95
carto::rc_ptr< carto::Volume< Point3df > > & ctrlDeformations()
Definition: ffd.h:61
FfdTransformation(const FfdTransformation &other)
Point3dd mmToSplineVox(const Point3dd &p) const
Definition: ffd.h:186
int getSizeY() const
Definition: ffd.h:90
int dimZ() const
Definition: ffd.h:88
float sizeZ() const
Definition: ffd.h:97
void updateCtrlKnot(int nx, int ny, int nz, const Point3df &newCtrlKnot)
Point3dd ffdCoord(const Point3dd &p_mm) const
Definition: ffd.h:82
const carto::Object options() const
FFD vector field deformation transform.
Definition: ffd.h:225
Point3dd deformation(const Point3dd &p_mm) const
SplineFfd(const carto::rc_ptr< carto::Volume< Point3df > > &other)
virtual void updateDimensions()
SplineFfd(const SplineFfd &other)
SplineFfd & operator=(const SplineFfd &other)
SplineFfd(int dimX=0, int dimY=1, int dimZ=1, float sizeX=1., float sizeY=1., float sizeZ=1.)
double spline3(double x) const
Definition: ffd.h:244
Pre-computed B-Spline values In the "order 0" case, the array is not used (the analytical expression ...
Definition: bspline.h:252
FFD vector field deformation transform.
Definition: ffd.h:294
TrilinearFfd & operator=(const TrilinearFfd &other)
TrilinearFfd(int dimX=0, int dimY=1, int dimZ=1, float sizeX=1., float sizeY=1., float sizeZ=1.)
Point3dd deformation(const Point3dd &p_mm) const
TrilinearFfd(const TrilinearFfd &other)
TrilinearFfd(const carto::rc_ptr< carto::Volume< Point3df > > &other)
Writer(const std::string &filename, carto::Object options=carto::none())
Definition: ffd.h:339
virtual bool write(const aims::FfdTransformation &obj, bool ascii=false, const std::string *format=0)
int getSizeY() const
std::vector< float > getVoxelSize() const
int getSizeX() const
int getSizeZ() const
Object none()