aimsalgo 6.0.0
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
21class Graph;
22
23namespace 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; }
63
65 bool isIdentity() const CARTO_OVERRIDE { return false; }
66
67 bool isDirect() const override;
68
69 //--- Control Knots ------------------------------------------------------
70 Point3df getCtrlKnot( int nx, int ny, int nz ) const;
71 void updateCtrlKnot( int nx, int ny, int nz, const Point3df & newCtrlKnot );
73 const carto::rc_ptr<carto::Volume<Point3df> > & newCtrlKnotGrid );
75 const carto::rc_ptr<carto::Volume<Point3df> > & newDeformationGrid );
76
77 //--- Modify -------------------------------------------------------------
78 void increaseResolution( const Point3d & addKnots );
79 // void inverseTransform();
80 // void estimateLocalDisplacement( const Point3df & voxelSize);
81
82 //--- Deformation --------------------------------------------------------
83 Point3dd deformation( const Point3dd& p_mm ) const;
84 Point3dd ffdCoord( const Point3dd& p_mm ) const
85 { return mmToSplineVox(p_mm); }
86
87 //--- Parameters ---------------------------------------------------------
88 int dimX() const { return _dimx; }
89 int dimY() const { return _dimy; }
90 int dimZ() const { return _dimz; }
91 int getSizeX() const { return _dimx; }
92 int getSizeY() const { return _dimy; }
93 int getSizeZ() const { return _dimz; }
94 std::vector<int> getSize() const
95 { std::vector<int> s( 3 ); s[0] = _dimx; s[1] = _dimy; s[2] = _dimz;
96 return s; }
97 float sizeX() const { return _vsx; }
98 float sizeY() const { return _vsy; }
99 float sizeZ() const { return _vsz; }
100 std::vector<float> getVoxelSize() const
101 { std::vector<float> v( 3 ); v[0] = _vsx; v[1] = _vsy; v[2] = _vsz;
102 return v; }
103 bool isFlat( int i ) const
104 {
105 switch(i)
106 {
107 case 0: return _flatx;
108 case 1: return _flaty;
109 case 2: return _flatz;
110 default: return false;
111 }
112 }
113 bool isXFlat() const { return _flatx; }
114 bool isYFlat() const { return _flaty; }
115 bool isZFlat() const { return _flatz; }
116 virtual void updateDimensions();
117
118 //--- Debug --------------------------------------------------------------
120 void writeDebugCtrlKnots( const std::string & filename ) const;
121 void writeDebugDeformations( const std::string & filename,
122 int dimX, int dimY, int dimZ,
123 float sizeX, float sizeY, float sizeZ ) const;
124
125 //--- Output -------------------------------------------------------------
126 void write( const std::string & filename ) const;
127
128 //--- Composition --------------------------------------------------------
130 const soma::Transformation3d & other ) const;
132 const carto::rc_ptr<soma::Transformation3d> & other ) const;
135 const carto::rc_ptr<soma::Transformation3d> & other ) const = 0;
137 const carto::rc_ptr<soma::Transformation3d> & other ) const = 0;
138
139 protected:
140 //--- Protected methods --------------------------------------------------
141 Point3dd splineVoxToMm( const Point3dd& p ) const;
142 Point3dd mmToSplineVox( const Point3dd& p ) const;
144 const carto::rc_ptr<carto::Volume<Point3df> > & newGrid );
145
146 virtual Point3dd _deformation( const Point3dd& p_mm ) const = 0;
147
150 float _vsx, _vsy, _vsz;
152 };
153
154 template <typename T>
155 inline
157 int dimX, int dimY, int dimZ,
158 const carto::rc_ptr<carto::Volume<T> > & test_volume ):
160 _dimx( dimX ), _dimy( dimY ), _dimz( dimZ ),
161 _flatx( dimX == 1 ), _flaty( dimY == 1 ), _flatz( dimZ == 1 )
162 {
163 _ctrlPointDelta = Point3df(0., 0., 0.);
164 _ctrlPointDelta.setVoxelSize(
165 _flatx ? test_volume->getVoxelSize()[0] : double(test_volume->getSizeX() - 1) / double(dimX - 1) * test_volume->getVoxelSize()[0],
166 _flaty ? test_volume->getVoxelSize()[1] : double(test_volume->getSizeY() - 1) / double(dimY - 1) * test_volume->getVoxelSize()[1],
167 _flatz ? test_volume->getVoxelSize()[2] : double(test_volume->getSizeZ() - 1) / double(dimZ - 1) * test_volume->getSizeZ()
168 );
170 }
171
172 template <typename T>
173 inline
175 const carto::Volume<T> & test_volume ):
177 _dimx( dimX ), _dimy( dimY ), _dimz( dimZ ),
178 _flatx( dimX == 1 ), _flaty( dimY == 1 ), _flatz( dimZ == 1 )
179 {
180 _ctrlPointDelta = Point3df(0., 0., 0.);
181 std::vector<float> vs = test_volume.getVoxelSize();
182 _ctrlPointDelta.setVoxelSize(
183 _flatx ? vs[0] : double(test_volume.getSizeX() - 1) / double(dimX - 1) * vs[0],
184 _flaty ? vs[1] : double(test_volume.getSizeY() - 1) / double(dimY - 1) * vs[1],
185 _flatz ? vs[2] : double(test_volume.getSizeZ() - 1) / double(dimZ - 1) * vs[2]
186 );
188 }
189
190 inline Point3dd
192 {
193 return Point3dd( p[0] * sizeX(),
194 p[1] * sizeY(),
195 p[2] * sizeZ() );
196 }
197
198 inline Point3dd
200 {
201 return Point3dd( p[0] / sizeX(),
202 p[1] / sizeY(),
203 p[2] / sizeZ() );
204 }
205
206 //==========================================================================
207 // FFD TRANSFORMATION
208 //==========================================================================
209
238 {
239 public:
240 //--- Constructor --------------------------------------------------------
241 SplineFfd( int dimX = 0, int dimY = 1, int dimZ = 1,
242 float sizeX = 1., float sizeY = 1., float sizeZ = 1. );
243 template <typename T>
244 SplineFfd( int dimX, int dimY, int dimZ,
245 const carto::rc_ptr<carto::Volume<T> > & test_volume );
246 template <typename T>
247 SplineFfd( int dimX, int dimY, int dimZ,
248 const carto::Volume<T> & test_volume );
249
250 SplineFfd( const SplineFfd & other );
252 SplineFfd & operator=( const SplineFfd & other );
253
254 virtual void updateDimensions();
255 //--- Deformation --------------------------------------------------------
256 Point3dd deformation( const Point3dd& p_mm ) const;
257 double spline3( double x ) const { return _spline(x); }
258
259 //--- Composition --------------------------------------------------------
261 const carto::rc_ptr<soma::Transformation3d> & other ) const;
263 const carto::rc_ptr<soma::Transformation3d> & other ) const;
264
265 private:
266 virtual Point3dd transformDouble( double x, double y, double z ) const;
267 virtual Point3dd _deformation( const Point3dd& p_mm ) const
268 { return deformation_private(p_mm); };
269 Point3dd deformation_private( const Point3dd& p_mm ) const;
270
271 const aims::TabulBSpline _spline;
272 std::vector<int> _mirrorcoefvecx;
273 std::vector<int> _mirrorcoefvecy;
274 std::vector<int> _mirrorcoefvecz;
275 int *_mirrorcoefx;
276 int *_mirrorcoefy;
277 int *_mirrorcoefz;
278 };
279
280 template <typename T>
281 inline
283 const carto::rc_ptr<carto::Volume<T> > & test_volume ):
284 FfdTransformation( dimX, dimY, dimZ, test_volume ),
285 _spline(3, 0)
286 {
287 }
288
289 template <typename T>
290 inline
292 const carto::Volume<T> & test_volume ):
293 FfdTransformation( dimX, dimY, dimZ, test_volume ),
294 _spline(3, 0)
295 {
296 }
297
298
299 //==========================================================================
300 // FFD TRILINEAR RESAMPLED TRANSFORMATION
301 //==========================================================================
302
313 {
314 public:
315 //--- Constructor --------------------------------------------------------
316 TrilinearFfd( int dimX = 0, int dimY = 1, int dimZ = 1,
317 float sizeX = 1., float sizeY = 1., float sizeZ = 1. );
318 template <typename T>
319 TrilinearFfd( int dimX, int dimY, int dimZ,
320 const carto::rc_ptr<carto::Volume<T> > & test_volume );
321
322 TrilinearFfd( const TrilinearFfd & other );
325
326 //--- Deformation --------------------------------------------------------
327 Point3dd deformation( const Point3dd& p_mm ) const;
328
329 //--- Composition --------------------------------------------------------
331 const carto::rc_ptr<soma::Transformation3d> & other ) const;
333 const carto::rc_ptr<soma::Transformation3d> & other ) const;
334
335 private:
336 virtual Point3dd transformDouble( double x, double y, double z ) const;
337 virtual Point3dd _deformation( const Point3dd& p_mm ) const
338 { return deformation_private(p_mm); };
339 Point3dd deformation_private( const Point3dd& p_mm ) const;
340 };
341
342 template <typename T>
343 inline
345 int dimX, int dimY, int dimZ,
346 const carto::rc_ptr<carto::Volume<T> > & test_volume ):
347 FfdTransformation( dimX, dimY, dimZ, test_volume )
348 {
349 }
350
351//============================================================================
352// FFD READER/WRITER
353//============================================================================
354
358 template<>
360 : public Writer<carto::Volume<Point3df> >
361 {
362 typedef Writer<carto::Volume<Point3df> > base;
363 public:
364 inline Writer(): base() {}
365 inline Writer( const std::string& filename,
367 base( filename, options ) {}
368 virtual ~Writer() {}
369 virtual bool write( const aims::FfdTransformation & obj,
370 bool ascii = false,
371 const std::string* format = 0 );
372 };
373
374} // namespace aims
375
376
377// ---
378
379namespace soma
380{
381
382 template <> inline std::string
383 DataTypeCode<aims::FfdTransformation>::objectType()
384 {
385 return "FFDTransformation";
386 }
387
388 template <> inline std::string
389 DataTypeCode<aims::FfdTransformation>::dataType()
390 {
391 return "VOID";
392 }
393
394 template <> inline std::string
395 DataTypeCode<aims::FfdTransformation>::name()
396 {
397 return "FFDTransformation";
398 }
399
400}
401
402
403#endif
#define CARTO_OVERRIDE
FFD vector field deformation transform.
Definition ffd.h:38
float sizeY() const
Definition ffd.h:98
void updateGridResolution(const carto::rc_ptr< carto::Volume< Point3df > > &newGrid)
virtual carto::rc_ptr< soma::Transformation3d > leftComposed(const carto::rc_ptr< soma::Transformation3d > &other) const =0
void updateAllCtrlKnot(const carto::rc_ptr< carto::Volume< Point3df > > &newCtrlKnotGrid)
virtual Point3dd _deformation(const Point3dd &p_mm) const =0
void increaseResolution(const Point3d &addKnots)
std::vector< int > getSize() const
Definition ffd.h:94
Point3dd deformation(const Point3dd &p_mm) const
carto::VolumeRef< Point3df > _ctrlPointDelta
Definition ffd.h:148
int getSizeZ() const
Definition ffd.h:93
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:113
void buildFromOther(const soma::Transformation3d &other)
int getSizeX() const
Definition ffd.h:91
Point3dd splineVoxToMm(const Point3dd &p) const
Definition ffd.h:191
bool isDirect() const override
int dimX() const
Definition ffd.h:88
carto::rc_ptr< carto::Volume< Point3df > > & ctrlDeformations()
Definition ffd.h:61
carto::rc_ptr< soma::Transformation3d > operator*(const soma::Transformation3d &other) const
FfdTransformation(const carto::rc_ptr< carto::Volume< Point3df > > &other)
Point3df getCtrlKnot(int nx, int ny, int nz) const
int dimY() const
Definition ffd.h:89
bool isZFlat() const
Definition ffd.h:115
virtual carto::rc_ptr< soma::Transformation3d > composed(const carto::rc_ptr< soma::Transformation3d > &other) const =0
virtual void updateDimensions()
FfdTransformation & operator=(const FfdTransformation &other)
bool isYFlat() const
Definition ffd.h:114
void writeDebugCtrlKnots(const std::string &filename) const
bool isFlat(int i) const
Definition ffd.h:103
void writeDebugDeformations(const std::string &filename, int dimX, int dimY, int dimZ, float sizeX, float sizeY, float sizeZ) const
std::vector< float > getVoxelSize() const
Definition ffd.h:100
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:97
FfdTransformation(const FfdTransformation &other)
Point3dd mmToSplineVox(const Point3dd &p) const
Definition ffd.h:199
int getSizeY() const
Definition ffd.h:92
int dimZ() const
Definition ffd.h:90
float sizeZ() const
Definition ffd.h:99
void updateCtrlKnot(int nx, int ny, int nz, const Point3df &newCtrlKnot)
Point3dd ffdCoord(const Point3dd &p_mm) const
Definition ffd.h:84
const carto::Object options() const
Point3dd deformation(const Point3dd &p_mm) const
SplineFfd & operator=(const SplineFfd &other)
virtual carto::rc_ptr< soma::Transformation3d > leftComposed(const carto::rc_ptr< soma::Transformation3d > &other) const
SplineFfd(const carto::rc_ptr< carto::Volume< Point3df > > &other)
virtual void updateDimensions()
SplineFfd(const SplineFfd &other)
SplineFfd(int dimX=0, int dimY=1, int dimZ=1, float sizeX=1., float sizeY=1., float sizeZ=1.)
virtual carto::rc_ptr< soma::Transformation3d > composed(const carto::rc_ptr< soma::Transformation3d > &other) const
double spline3(double x) const
Definition ffd.h:257
Pre-computed B-Spline values In the "order 0" case, the array is not used (the analytical expression ...
Definition bspline.h:252
TrilinearFfd(int dimX=0, int dimY=1, int dimZ=1, float sizeX=1., float sizeY=1., float sizeZ=1.)
virtual carto::rc_ptr< soma::Transformation3d > composed(const carto::rc_ptr< soma::Transformation3d > &other) const
TrilinearFfd & operator=(const TrilinearFfd &other)
Point3dd deformation(const Point3dd &p_mm) const
TrilinearFfd(const TrilinearFfd &other)
virtual carto::rc_ptr< soma::Transformation3d > leftComposed(const carto::rc_ptr< soma::Transformation3d > &other) const
TrilinearFfd(const carto::rc_ptr< carto::Volume< Point3df > > &other)
Writer(const std::string &filename, carto::Object options=carto::none())
Definition ffd.h:365
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()
AimsVector< float, 3 > Point3df
AimsVector< int16_t, 3 > Point3d
AimsVector< double, 3 > Point3dd