cmtkDataGrid.h

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 2004-2011 SRI International
00004 //
00005 //  Copyright 1997-2010 Torsten Rohlfing
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2752 $
00026 //
00027 //  $LastChangedDate: 2011-01-17 11:33:31 -0800 (Mon, 17 Jan 2011) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #ifndef __cmtkDataGrid_h_included_
00034 #define __cmtkDataGrid_h_included_
00035 
00036 #include <cmtkconfig.h>
00037 
00038 #include <Base/cmtkMacros.h>
00039 #include <Base/cmtkTypes.h>
00040 #include <Base/cmtkTypedArray.h>
00041 #include <Base/cmtkFixedVector.h>
00042 #include <Base/cmtkScalarImage.h>
00043 #include <Base/cmtkRegion.h>
00044 #include <Base/cmtkMetaInformationObject.h>
00045 #include <Base/cmtkAnatomicalOrientation.h>
00046 
00047 #include <System/cmtkSmartPtr.h>
00048 #include <System/cmtkThreads.h>
00049 
00050 #include <vector>
00051 
00052 namespace
00053 cmtk
00054 {
00055 
00058 
00066 class DataGrid :
00068   public MetaInformationObject
00069 {
00070 public:
00072   typedef DataGrid Self;
00073 
00075   typedef SmartPointer<Self> SmartPtr;
00076 
00078   typedef SmartConstPointer<Self> SmartConstPtr;
00079 
00081   typedef Region<3,int> RegionType;
00082 
00084   typedef RegionType::IndexType IndexType;
00085 
00087   typedef FixedVector<3,Types::Coordinate> SpaceVectorType;
00088 
00090   Self::IndexType m_Dims;
00091 
00093   cmtkGetSetMacro(TypedArray::SmartPtr,Data);
00094 
00095 public:
00097   DataGrid() : 
00098     m_Data( NULL )
00099   {}
00100   
00102   DataGrid( const Self::IndexType& dims, TypedArray::SmartPtr& data = TypedArray::SmartPtr::Null ) 
00103     : m_Dims( dims ), 
00104       m_Data( data )
00105   {
00106     this->m_CropRegion = this->GetWholeImageRegion();
00107   }
00108   
00110   virtual ~DataGrid() {}
00111 
00113   bool GridMatches( const Self& other ) const
00114   {
00115     return (this->m_Dims == other.m_Dims);
00116   }
00117 
00119   virtual DataGrid* GetDownsampledAndAveraged( const int (&downsample)[3] ) const;
00120 
00143   const DataGrid::SmartPtr GetReoriented( const char* newOrientation = AnatomicalOrientation::ORIENTATION_STANDARD ) const;
00144   
00149   void SetDims( const Self::IndexType& dims );
00150 
00152   const Self::IndexType GetDims() const
00153   {
00154     return this->m_Dims;
00155   }
00156 
00161   virtual TypedArray::SmartPtr CreateDataArray( const ScalarDataType dataType, const bool setToZero = false );
00162 
00164   size_t GetNumberOfPixels () const { return this->m_Dims[0]*this->m_Dims[1]*this->m_Dims[2]; }
00165 
00167   bool IndexIsInRange( const int x, const int y, const int z ) const
00168   {
00169     return (x>=0) && (x<this->m_Dims[0]) && (y>=0) && (y<this->m_Dims[1]) && (z>=0) && (z<this->m_Dims[2]);
00170   }
00171 
00173   size_t GetOffsetFromIndex( const int x, const int y, const int z ) const 
00174   {
00175     return x + nextJ * y + nextK * z;
00176   }
00177 
00179   void GetIndexFromOffset( const size_t offset, int& x, int& y, int& z ) const 
00180   {
00181     z = offset / nextK;
00182     y = (offset % nextK) / nextJ;
00183     x = (offset % nextK) % nextJ;
00184   }
00185 
00187   bool GetDataAt ( Types::DataItem& data, const size_t offset ) const 
00188   {
00189     return this->m_Data->Get( data, offset );
00190   }
00191 
00193   void SetDataAt ( const Types::DataItem data, const size_t offset )
00194   {
00195     this->m_Data->Set( data, offset );
00196   }
00197   
00199   bool GetDataAt ( Types::DataItem& data, const int x, const int y, const int z ) const
00200   {
00201     return this->GetDataAt( data, this->GetOffsetFromIndex( x, y, z ) );
00202   }
00203 
00205   void SetDataAt ( const Types::DataItem data, const int x, const int y, const int z )
00206   {
00207     this->SetDataAt( data, this->GetOffsetFromIndex( x, y, z ) );
00208   }
00209 
00211   Types::DataItem GetDataAt ( const int x, const int y, const int z, const Types::DataItem defaultValue = 0.0 ) const
00212   {
00213     Types::DataItem value;
00214     if ( this->GetDataAt( value, this->GetOffsetFromIndex( x, y, z ) ) )
00215       return value;
00216     else
00217       return defaultValue;
00218   }
00219 
00221   Types::DataItem GetDataAt ( const size_t offset, const Types::DataItem defaultValue = 0.0 ) const
00222   {
00223     Types::DataItem value;
00224     if ( this->GetDataAt( value, offset ) )
00225       return value;
00226     else
00227       return defaultValue;
00228   }
00229 
00234   TypedArray::SmartPtr GetDataMirrorPlane( const int axis = AXIS_X ) const;
00235 
00237   void ApplyMirrorPlane( const int axis = AXIS_X );
00238 
00239 private:
00241   static void MirrorPlaneInPlace( TypedArray& data, const Self::IndexType& dims, const int axis = AXIS_X );
00242 
00243 public:
00246   Self::RegionType& CropRegion()
00247   {
00248     return this->m_CropRegion;
00249   }
00250 
00255   virtual void SetCropRegion( const Self::RegionType& region );
00256 
00259   const Self::RegionType& CropRegion() const
00260   {
00261     return this->m_CropRegion;
00262   }
00263 
00266   int GetCropRegionNumVoxels() const;
00267 
00269   const RegionType GetWholeImageRegion() const;
00270 
00272   const Self::IndexType GetCropRegionIncrements() const;
00273 
00281   void AutoCrop( const Types::DataItem threshold, const bool recrop = false, const int margin = 0 );
00282 
00284   void FillCropBackground( const Types::DataItem value );
00285 
00287   TypedArray::SmartPtr GetCroppedData() const;
00288 
00290   int GetNextI() const { return nextI; }
00291   int GetNextJ() const { return nextJ; }
00292   int GetNextK() const { return nextK; }
00293   int GetNextIJ() const { return nextIJ; }
00294   int GetNextIK() const { return nextIK; }
00295   int GetNextJK() const { return nextJK; }
00296   int GetNextIJK() const { return nextIJK; }
00297   
00299   virtual FixedVector<3,Types::Coordinate> GetCenterOfMassGrid() const;
00300   
00302   virtual FixedVector<3,Types::Coordinate> GetCenterOfMassGrid( FixedVector<3,Types::Coordinate>& firstOrderMoment ) const;
00303   
00305   template<class TAccumulator>
00306   ScalarImage* ComputeProjection( const int axis ) const;
00307   
00310   virtual ScalarImage* GetOrthoSlice( const int axis, const unsigned int plane ) const;
00311   
00314   Self::SmartPtr ExtractSlice( const int axis, const int plane ) const
00315   {
00316     return Self::SmartPtr( this->ExtractSliceVirtual( axis, plane ) );
00317   }
00318   
00321   virtual void SetOrthoSlice( const int axis, const unsigned int idx, const ScalarImage* slice );
00322 
00324   TypedArray::SmartPtr GetDataMirrored( const int axis = AXIS_X ) const;
00325 
00327   void Print() const;
00328 
00329 protected:
00346   bool TrilinearInterpolation( Types::DataItem& data, const int x, const int y, const int z, const Self::SpaceVectorType& location, const Types::Coordinate* cellFrom, const Types::Coordinate* cellTo ) const;
00347 
00364   template<class TData>
00365   inline TData TrilinearInterpolation
00366   ( const TData* dataPtr, const int x, const int y, const int z, const Self::SpaceVectorType& gridPosition, const Types::Coordinate* cellFrom, const Types::Coordinate* cellTo ) const;
00367 
00372   template<class TData,class TOutputIterator>
00373   inline void TrilinearInterpolation
00374   ( TOutputIterator result ,
00375     const std::vector<TData*>& dataPtr , 
00376     const int x , 
00377     const int y , 
00378     const int z ,
00379     const Types::Coordinate fracX , 
00380     const Types::Coordinate fracY , 
00381     const Types::Coordinate fracZ  ) const;
00382 
00384   int nextI;
00385 
00387   int nextJ;
00388 
00390   int nextK;
00391 
00393   int nextIJ;
00394   
00396   int nextIK;
00397 
00399   int nextJK;
00400 
00402   int nextIJK;
00403 
00406   virtual Self* ExtractSliceVirtual( const int axis , const int plane  ) const;
00407 
00408 private:
00411   Self::RegionType m_CropRegion;
00412 };
00413 
00415 
00416 } // namespace cmtk
00417 
00418 #include "cmtkDataGrid.txx"
00419 
00420 #endif // #ifndef __cmtkDataGrid_h_included_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines