Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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 ) != 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;
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 }