/* Description: Tensorfields in 2D and 3D When writing new functions: 1) z-dimension should always default to 1 in a constructor and to 0 in a function, so that tensorfield(256 256, 256); is the constructor for a 256*256*256 field of tensors get(0, 0, 0); returns the first element in this example get(255, 255, 255); returns the last element in this example Other functions - tensorfield(path, 256, 256, 9); reads 9 slices from a serie located in path. Path ends with -S as files created by xpath(?) do Author: Raimundo Sierra www.rsierra.com Copyright: Copyright (c) 2000 Raimundo Sierra. All rights reserved. LICENSE: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Institution: Surgical Planning Laboratory Department of Radiology Brigham and Women's Hospital Harvard Medical School MA 02115 USA Date: 11.2000 - 3.2001 Modifications: */ #ifndef _tensorfield #define _tensorfield 1 #include #include #include #include #include "basefield.h" #include "background.h" #include "tensor.h" #include "vtkTensors.h" #include "vtkScalars.h" #ifdef debug extern int fieldcounter; // counts calls to constructors extern int fielddestructorcounter; // counts calls to destructors #endif class tensorfield: public basefield { private: tensor *_field; // pointer to the array of tensors, 3D representation: // [x + y*_dimx + z*_dimx*_dimz] tensorfield(const tensorfield &field); // do not want a copy constructor to // avoid creating unwanted copies of a tensorfield. // read single image from output of /d/lsdi/bin/LSDIrecon // to compute tensorvalues, called from read_tensorslice //short* read_pic(short* image, char path_file[], int offset=0); public: // constructors // constructor which reads raw data from disk // and computes the tensors // dimz corresponds to the number of slices // if path is an xml-file then extract information // from the xml-file and ignore dimensions tensorfield(const char path[], const int dimx=256, const int dimy=256, const int dimz=1); // constructor that creates empty tensorfield tensorfield(const int dimx=256, const int dimy=256, const int dimz=1); // destructor ~tensorfield(); // basic functions: storage, set and get values // get tensor at position xyz tensor* get(const int x, const int y, const int z=0); tensor* get(const int position); // each array contains on component of the tensorfield in the same order as the field void separate(float * array1, float * array2, float * array3, float * array4, float * array5, float * array6); // opposite function: merge arrays of size of field into tensorfield void merge (float * array1, float * array2, float * array3, float * array4, float * array5, float * array6); void merge (float * array1, float * array2, float * array3, float * array4, float * array5, float * array6, float * array7, float * array8, float * array9); // set tensor at position xyz to values given by t void set(const tensor t, const int x, const int y, const int z=0); // read images le1x to le3z for a single slice to // derive tensors void read_tensorslice(const char path[], const int slice_no = 0); void load(const char path[]); // load tensorfield from disc // save tensorfield to disc void save(const char path[], int offset[3]=NULL, int windowsize[3]=NULL); // output tensor at position xyz; not really needed since // tensor can be printed throu // cout << myfield.get(int, int, int); void print(const int x, const int y, const int z=0) const; // transform this classes tensorfield into a vtk-Tensorfield // no boundarie-check on offset and window void tensorField2vtkField(const int offset[3], const int window[3], vtkTensors * newTensors) const; // create a scalar vtk field // no boundarie-check on offset and window void det2vtkScalars(const int offset[3], const int window[3], vtkScalars *newScalars) const; // functions which process the actual tensordata // remove the strips outside the object (inside=0) void remove_strips(const int inside=0); // inside = 1 also removes the strips inside the object void smooth(const int filterlength=3); // downsample this field into smallfield // Boundaries are checked // Post: the tensorfield is smoothed!! void downsampleSlices(tensorfield &smallfield, const int factor=2, const int smoothlength=3); void roundness(float * pointarray); // pointarray = det()/trace() at each point // pointarray = det()^(1/dim)/(trace()+sigma) at each point void roundnessCF(float * pointarray, const float thresh=0.01); void trace(float * array) const; // array = trace() at each point void det (float * array) const; // array = det() at each point void mask(background &bg); }; #endif