cmtkClassStreamWarpXform.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
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: 2464 $
00026 //
00027 //  $LastChangedDate: 2010-10-19 09:54:33 -0700 (Tue, 19 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torsten_at_home $
00030 //
00031 */
00032 
00033 #include "cmtkClassStream.h"
00034 
00035 #include <IO/cmtkClassStreamAffineXform.h>
00036 
00037 namespace
00038 cmtk
00039 {
00040 
00043 
00044 ClassStream& 
00045 ClassStream::operator << ( const WarpXform *warpXform )
00046 {
00047   return this->PutWarp( warpXform );
00048 }
00049 
00050 ClassStream& 
00051 ClassStream::PutWarp
00052 ( const WarpXform *warpXform )
00053 {
00054   const Types::Coordinate *nCoeff = warpXform->m_Parameters;
00055   
00056   if ( dynamic_cast<const SplineWarpXform*>( warpXform ) )
00057     this->Begin( "spline_warp" );
00058   
00059   if ( warpXform->GetInitialAffineXform() )
00060     *this << (*warpXform->GetInitialAffineXform());
00061   
00062   this->WriteBool ( "absolute", true );
00063   this->WriteIntArray( "dims", warpXform->m_Dims.begin(), 3 );
00064   
00065   this->WriteCoordinateArray( "domain", warpXform->Domain.begin(), 3 );
00066   this->WriteCoordinateArray( "origin", warpXform->m_Offset.begin(), 3 );
00067   this->WriteCoordinateArray( "coefficients", nCoeff, warpXform->m_NumberOfParameters, 3 );
00068   
00069   const BitVector* activeFlags = warpXform->GetActiveFlags();
00070   if ( activeFlags ) 
00071     {
00072     this->WriteBoolArray( "active", activeFlags->GetBitVector(), warpXform->m_NumberOfParameters, 30 );
00073     }                    
00074   
00075   this->End();
00076   
00077   return *this;
00078 }
00079 
00080 ClassStream&
00081 ClassStream::Get
00082 ( WarpXform::SmartPtr& warpXform, const AffineXform* initialXform )
00083 {
00084   WarpXform* warp;
00085   this->Get( warp, initialXform );
00086   warpXform = WarpXform::SmartPtr( warp );
00087   return *this;
00088 }
00089 
00090 ClassStream&
00091 ClassStream::Get
00092 ( WarpXform*& warpXform, const AffineXform* initialXform )
00093 {
00094   warpXform = NULL;
00095 
00096   int WarpType = -1;
00097   if ( this->Seek( "spline_warp" ) == TYPEDSTREAM_OK ) 
00098     WarpType = 1;
00099   else
00100     if ( this->Seek( "linear_warp" ) == TYPEDSTREAM_OK )
00101       WarpType = 0;
00102     else 
00103       {
00104       this->Rewind();
00105       if ( this->Seek( "registration", true /*forward*/ ) != TYPEDSTREAM_OK )
00106         {
00107         return *this;
00108         }
00109       if ( this->Seek( "spline_warp" ) == TYPEDSTREAM_OK ) 
00110         WarpType = 1;
00111       else
00112         if ( this->Seek( "linear_warp" ) == TYPEDSTREAM_OK )
00113           WarpType = 0;
00114         else
00115           return *this;
00116       }
00117   
00118   AffineXform::SmartPtr initialInverse( NULL );
00119   if ( initialXform == NULL ) 
00120     {
00121     AffineXform::SmartPtr newInitialXform;
00122     *this >> newInitialXform;
00123     initialInverse = AffineXform::SmartPtr( newInitialXform );
00124     } 
00125   else 
00126     {
00127     initialInverse = AffineXform::SmartPtr( initialXform->MakeInverse() );
00128     }
00129   
00130   int absolute = this->ReadBool( "absolute", 0 );
00131   
00132   int dims[3];
00133   if ( TYPEDSTREAM_OK != this->ReadIntArray( "dims", dims, 3 ) ) 
00134     {
00135     return *this;
00136     }
00137   
00138   int numControlPoints = dims[0] * dims[1] * dims[2];
00139   int numberOfParameters = 3 * numControlPoints;
00140   CoordinateVector::SmartPtr parameters( new CoordinateVector( numberOfParameters ) );
00141   Types::Coordinate *Coefficients = parameters->Elements;
00142   
00143   Vector3D domain;
00144   Vector3D origin;
00145 
00146   if ( this->ReadCoordinateArray( "domain", domain.begin(), 3 ) != TYPEDSTREAM_OK )
00147     this->ReadCoordinateArray( "extent", domain.begin(), 3 );
00148   
00149   int readOrigin = this->ReadCoordinateArray( "origin", origin.begin(), 3 );
00150   this->ReadCoordinateArray( "coefficients", Coefficients, numberOfParameters );
00151   if ( !absolute && (readOrigin == TYPEDSTREAM_OK) ) 
00152     {
00153     Types::Coordinate *p = Coefficients;
00154     for ( int z=0; z<dims[2]; ++z )
00155       for ( int y=0; y<dims[1]; ++y )
00156         for ( int x=0; x<dims[0]; ++x, p+=3 ) 
00157           {
00158           if ( WarpType == 0 ) 
00159             {
00160             p[0] += (origin[0] + x * domain[0]/(dims[0]-1));
00161             p[1] += (origin[1] + y * domain[1]/(dims[1]-1));
00162             p[2] += (origin[2] + z * domain[2]/(dims[2]-1));
00163             } 
00164           else
00165             {
00166             p[0] += (origin[0] + x * domain[0]/(dims[0]-3));
00167             p[1] += (origin[1] + y * domain[1]/(dims[1]-3));
00168             p[2] += (origin[2] + z * domain[2]/(dims[2]-3));
00169             }
00170           }
00171     }
00172   
00173   switch ( WarpType ) 
00174     {
00175     case 0: 
00176       warpXform = NULL; // linear warp no longer supported
00177       break;
00178     case 1: 
00179       warpXform = new SplineWarpXform( domain, SplineWarpXform::IndexType( dims ), parameters, initialInverse );
00180       break;
00181     };
00182   
00183   byte *active = Memory::AllocateArray<byte>( (numberOfParameters / 8)+1 );
00184   if ( this->ReadBoolArray( "active", active, numberOfParameters ) == TYPEDSTREAM_OK ) 
00185     {
00186     BitVector::SmartPtr bitSet( new BitVector( numberOfParameters, active ) );
00187     warpXform->SetActiveFlags( bitSet );
00188     } 
00189   else 
00190     {
00191     Memory::DeleteArray( active );
00192     }
00193   
00194   this->End();
00195 
00196   if ( warpXform )
00197     {
00198     warpXform->m_MetaInformation[META_SPACE] = AnatomicalOrientation::ORIENTATION_STANDARD;
00199     }
00200   
00201   return *this;
00202 }
00203 
00204 ClassStream& 
00205 ClassStream::operator >> ( WarpXform::SmartPtr& warpXform )
00206 {
00207   this->Get( warpXform );
00208   return *this; 
00209 }
00210 
00211 ClassStream& 
00212 ClassStream::operator >> ( WarpXform*& warpXform )
00213 {
00214   this->Get( warpXform );
00215   return *this; 
00216 }
00217 
00218 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines