20 #ifndef _MIRTKBIASFIELD_H 22 #define _MIRTKBIASFIELD_H 25 #include "mirtk/Point.h" 26 #include "mirtk/Matrix.h" 28 #include "mirtk/Transformation.h" 30 #define MIRTKBIASFIELD_MAGIC 815008 32 #define MIRTKBIASFIELD_BSPLINE 1 33 #define MIRTKBIASFIELD_POLYNOMIAL 2 37 class BiasField :
public Object
39 mirtkAbstractMacro(BiasField);
83 static double ***
Allocate (
double ***,
int,
int,
int);
86 static double ***
Deallocate(
double ***,
int,
int,
int);
89 virtual void UpdateMatrix();
97 virtual double Approximate(
double *,
double *,
double *,
double *,
int) = 0;
100 virtual void WeightedLeastSquares(
double *x1,
double *y1,
double *z1,
double *bias,
double *weights,
int no)=0;
107 virtual void Interpolate(
double* bias) = 0;
110 virtual void Subdivide() = 0;
113 virtual int GetX()
const;
116 virtual int GetY()
const;
119 virtual int GetZ()
const;
122 virtual int NumberOfDOFs()
const;
125 virtual void GetSpacing(
double &,
double &,
double &)
const;
128 virtual void PutOrientation(
double *,
double *,
double *);
131 virtual void GetOrientation(
double *,
double *,
double *)
const;
134 virtual void Put(
int,
double);
137 virtual void Put(
int,
int,
int,
double);
140 virtual double Get(
int)
const;
143 virtual double Get(
int,
int,
int)
const;
146 virtual void WorldToLattice(
double &,
double &,
double &)
const;
149 virtual void WorldToLattice(Point &)
const;
152 virtual void LatticeToWorld(
double &,
double &,
double &)
const;
155 virtual void LatticeToWorld(Point &)
const;
158 virtual void IndexToLattice(
int index,
int& i,
int& j,
int& k)
const;
161 virtual int LatticeToIndex(
int i,
int j,
int k)
const;
164 virtual void ControlPointLocation(
int,
double &,
double &,
double &)
const;
167 virtual Point ControlPointLocation(
int)
const;
170 virtual void PutBoundingBox(Point, Point);
173 virtual void PutBoundingBox(
double,
double,
double,
174 double,
double,
double);
177 virtual void BoundingBox(Point &, Point &)
const;
180 virtual void BoundingBox(
double &,
double &,
double &,
181 double &,
double &,
double &)
const;
187 virtual void BoundingBox(
int, Point &, Point &,
double = 1)
const;
193 virtual void BoundingBox(
int,
double &,
double &,
double &,
194 double &,
double &,
double &,
double = 1)
const;
200 virtual void BoundingBox(GreyImage *,
int,
int &,
int &,
int &,
201 int &,
int &,
int &,
double = 1)
const;
204 virtual double Bias(
double,
double,
double) = 0;
207 virtual void Read (
char *) = 0;
210 virtual void Write(
char *) = 0;
213 virtual void Print() = 0;
217 inline int BiasField::GetX()
const 222 inline int BiasField::GetY()
const 227 inline int BiasField::GetZ()
const 232 inline int BiasField::NumberOfDOFs()
const 237 inline double BiasField::Get(
int index)
const 241 if (index >= _x*_y*_z) {
242 std::cerr <<
"BiasField::Get: No such dof" << std::endl;
246 j = index%(_y*_z)/_z;
247 k = index%(_y*_z)%_z;
248 return _data[k][j][i];
251 inline double BiasField::Get(
int i,
int j,
int k)
const 253 if ((i < 0) || (i >= _x) || (j < 0) || (j >= _y) || (k < 0) || (k >= _z)) {
254 std::cerr <<
"BiasField::Get: No such dof" << std::endl;
257 return _data[k][j][i];
260 inline void BiasField::Put(
int index,
double x)
265 if (index >= _x*_y*_z) {
266 std::cerr <<
"BiasField::Put: No such dof" << std::endl;
270 j = index%(_y*_z)/_z;
271 k = index%(_y*_z)%_z;
275 inline void BiasField::Put(
int i,
int j,
int k,
double x)
277 if ((i < 0) || (i >= _x) || (j < 0) || (j >= _y) || (k < 0) || (k >= _z)) {
278 std::cerr <<
"BiasField::Put: No such dof" << std::endl;
284 inline void BiasField::GetSpacing(
double &dx,
double &dy,
double &dz)
const 291 inline void BiasField::PutOrientation(
double *xaxis,
double *yaxis,
double *zaxis)
293 _xaxis[0] = xaxis[0];
294 _xaxis[1] = xaxis[1];
295 _xaxis[2] = xaxis[2];
296 _yaxis[0] = yaxis[0];
297 _yaxis[1] = yaxis[1];
298 _yaxis[2] = yaxis[2];
299 _zaxis[0] = zaxis[0];
300 _zaxis[1] = zaxis[1];
301 _zaxis[2] = zaxis[2];
303 this->UpdateMatrix();
306 inline void BiasField::GetOrientation(
double *xaxis,
double *yaxis,
double *zaxis)
const 308 xaxis[0] = _xaxis[0];
309 xaxis[1] = _xaxis[1];
310 xaxis[2] = _xaxis[2];
311 yaxis[0] = _yaxis[0];
312 yaxis[1] = _yaxis[1];
313 yaxis[2] = _yaxis[2];
314 zaxis[0] = _zaxis[0];
315 zaxis[1] = _zaxis[1];
316 zaxis[2] = _zaxis[2];
319 inline void BiasField::PutBoundingBox(
double x1,
double y1,
double z1,
double x2,
double y2,
double z2)
322 _origin._x = (x2 + x1) / 2.0;
323 _origin._y = (y2 + y1) / 2.0;
324 _origin._z = (z2 + z1) / 2.0;
326 double a = x1 * _xaxis[0] + y1 * _xaxis[1] + z1 * _xaxis[2];
327 double b = x1 * _yaxis[0] + y1 * _yaxis[1] + z1 * _yaxis[2];
328 double c = x1 * _zaxis[0] + y1 * _zaxis[1] + z1 * _zaxis[2];
332 a = x2 * _xaxis[0] + y2 * _xaxis[1] + z2 * _xaxis[2];
333 b = x2 * _yaxis[0] + y2 * _yaxis[1] + z2 * _yaxis[2];
334 c = x2 * _zaxis[0] + y2 * _zaxis[1] + z2 * _zaxis[2];
341 _x = round((x2-x1)/_dx) +1;
342 _y = round((y2-y1)/_dy) +1;
343 _z = round((z2-z1)/_dz) +1;
344 _dx = (x2 - x1) / (_x - 1);
345 _dy = (y2 - y1) / (_y - 1);
347 _dz = (z2 - z1) / (_z - 1);
352 this->UpdateMatrix();
355 inline void BiasField::PutBoundingBox(Point p1, Point p2)
357 this->PutBoundingBox(p1._x, p1._y, p1._z, p2._x, p2._y, p2._z);
360 inline void BiasField::WorldToLattice(
double &x,
double &y,
double &z)
const 365 a = _matW2L(0, 0)*x+_matW2L(0, 1)*y+_matW2L(0, 2)*z+_matW2L(0, 3);
366 b = _matW2L(1, 0)*x+_matW2L(1, 1)*y+_matW2L(1, 2)*z+_matW2L(1, 3);
367 c = _matW2L(2, 0)*x+_matW2L(2, 1)*y+_matW2L(2, 2)*z+_matW2L(2, 3);
375 inline void BiasField::WorldToLattice(Point &p)
const 377 this->WorldToLattice(p._x, p._y, p._z);
380 inline void BiasField::LatticeToWorld(
double &x,
double &y,
double &z)
const 385 a = _matL2W(0, 0)*x+_matL2W(0, 1)*y+_matL2W(0, 2)*z+_matL2W(0, 3);
386 b = _matL2W(1, 0)*x+_matL2W(1, 1)*y+_matL2W(1, 2)*z+_matL2W(1, 3);
387 c = _matL2W(2, 0)*x+_matL2W(2, 1)*y+_matL2W(2, 2)*z+_matL2W(2, 3);
395 inline void BiasField::LatticeToWorld(Point &p)
const 397 this->LatticeToWorld(p._x, p._y, p._z);
400 inline void BiasField::IndexToLattice(
int index,
int& i,
int& j,
int& k)
const 403 if (index >= _x*_y*_z) {
405 if (index >= _x*_y*_z) {
410 j = index%(_y*_z)/_z;
411 k = index%(_y*_z)%_z;
414 inline int BiasField::LatticeToIndex(
int i,
int j,
int k)
const 416 return i * _y * _z + j * _z + k;
int Read(const char *name, UniquePtr< double[]> &data, int *dtype=nullptr, ImageAttributes *attr=nullptr, void *=nullptr, const char *scalars_name=nullptr, bool cell_data=false)
Read data sequence from any supported input file type.
string Get(const ParameterList ¶ms, string name)
Get parameter value from parameters list.
void Allocate(Type *&matrix, int n)
Allocate 1D array.
void Deallocate(Type *&p)
Deallocate 1D array.
std::ostream & Print(std::ostream &os, T value)
Print single argument to output stream.