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 #ifndef __cmtkGroupwiseRegistrationFunctionalXformTemplate_Affine_h_included_
00034 #define __cmtkGroupwiseRegistrationFunctionalXformTemplate_Affine_h_included_
00035
00036 #include <Base/cmtkTransformedVolumeAxes.h>
00037 #include <IO/cmtkClassStream.h>
00038
00039 namespace
00040 cmtk
00041 {
00042
00047 template<>
00048 class GroupwiseRegistrationFunctionalXformTemplate<AffineXform> :
00050 public GroupwiseRegistrationFunctionalXformTemplateBase<AffineXform>
00051 {
00052 public:
00054 typedef GroupwiseRegistrationFunctionalXformTemplateBase<AffineXform> Superclass;
00055
00057 typedef GroupwiseRegistrationFunctionalXformTemplate<AffineXform> Self;
00058
00060 typedef SmartPointer<Self> SmartPtr;
00061
00063 GroupwiseRegistrationFunctionalXformTemplate()
00064 : m_XformNumberDOFs( 9 )
00065 {
00066 this->m_ParametersPerXform = AffineXform::TotalNumberOfParameters;
00067 }
00068
00070 virtual ~GroupwiseRegistrationFunctionalXformTemplate() {}
00071
00073 void SetXformNumberDOFs( const int numberDOFs )
00074 {
00075 this->m_XformNumberDOFs = numberDOFs;
00076 std::vector<Xform::SmartPtr>::iterator it = this->m_XformVector.begin();
00077 while ( it != this->m_XformVector.end() )
00078 {
00079 AffineXform::SmartPtr::DynamicCastFrom(*it)->SetNumberDOFs( this->m_XformNumberDOFs );
00080 ++it;
00081 }
00082 }
00083
00086 void SetXforms( const std::vector<AffineXform::SmartPtr>& xformVector )
00087 {
00088 this->m_XformVector.resize( xformVector.size() );
00089 for ( size_t i = 0; i < this->m_XformVector.size(); ++i )
00090 {
00091 AffineXform::SmartPtr xform( new AffineXform( *(xformVector[i]) ) );
00092 xform->SetNumberDOFs( this->m_XformNumberDOFs );
00093 xform->SetUseLogScaleFactors( true );
00094
00095 const Vector3D center = this->m_ImageVector[i]->GetCenterCropRegion();
00096 xform->ChangeCenter( center );
00097
00098 this->m_XformVector[i] = xform;
00099 }
00100 }
00101
00102 protected:
00104 int m_XformNumberDOFs;
00105
00113 virtual void InterpolateImage( const size_t idx, byte* const destination )
00114 {
00115 const TransformedVolumeAxes gridHash( *this->m_TemplateGrid, this->GetXformByIndex( idx ) );
00116
00117 ThreadPool& threadPool = ThreadPool::GetGlobalThreadPool();
00118
00119 std::vector<InterpolateImageThreadParameters> params( 4 * threadPool.GetNumberOfThreads() );
00120 for ( size_t thread = 0; thread < params.size(); ++thread )
00121 {
00122 params[thread].thisObject = this;
00123 params[thread].m_Idx = idx;
00124 params[thread].m_Destination = destination;
00125 params[thread].m_HashX = gridHash[0];
00126 params[thread].m_HashY = gridHash[1];
00127 params[thread].m_HashZ = gridHash[2];
00128 }
00129
00130 if ( (this->m_ProbabilisticSampleDensity > 0) && (this->m_ProbabilisticSampleDensity < 1) )
00131 threadPool.Run( InterpolateImageProbabilisticThread, params );
00132 else
00133 threadPool.Run( InterpolateImageThread, params );
00134 }
00135
00137 static void InterpolateImageThread( void *const args, const size_t taskIdx, const size_t taskCnt, const size_t, const size_t )
00138 {
00139 InterpolateImageThreadParameters* threadParameters = static_cast<InterpolateImageThreadParameters*>( args );
00140
00141 const Self* This = threadParameters->thisObject;
00142 const size_t idx = threadParameters->m_Idx;
00143 byte* destination = threadParameters->m_Destination;
00144
00145 const UniformVolume* target = This->m_ImageVector[idx];
00146
00147 const byte paddingValue = This->m_PaddingValue;
00148 const byte backgroundValue = This->m_UserBackgroundFlag ? This->m_PrivateUserBackgroundValue : paddingValue;
00149
00150 Vector3D v;
00151 byte value;
00152 const byte* dataPtr = static_cast<const byte*>( target->GetData()->GetDataPtr() );
00153
00154 const int dimsX = This->m_TemplateGrid->GetDims()[AXIS_X];
00155 const int dimsY = This->m_TemplateGrid->GetDims()[AXIS_Y];
00156 const int dimsZ = This->m_TemplateGrid->GetDims()[AXIS_Z];
00157
00158 const int rowCount = ( dimsY * dimsZ );
00159 const int rowFrom = ( rowCount / taskCnt ) * taskIdx;
00160 const int rowTo = ( taskIdx == (taskCnt-1) ) ? rowCount : ( rowCount / taskCnt ) * ( taskIdx + 1 );
00161 int rowsToDo = rowTo - rowFrom;
00162
00163 int yFrom = rowFrom % dimsY;
00164 int zFrom = rowFrom / dimsY;
00165
00166 UniformVolume::CoordinateVectorType planeStart, rowStart;
00167 byte *wptr = destination + rowFrom * dimsX;
00168 for ( int z = zFrom; (z < dimsZ) && rowsToDo; ++z )
00169 {
00170 planeStart = threadParameters->m_HashZ[z];
00171 for ( int y = yFrom; (y < dimsY) && rowsToDo; yFrom = 0, ++y, --rowsToDo )
00172 {
00173 (rowStart = planeStart) += threadParameters->m_HashY[y];
00174 for ( int x = 0; x < dimsX; ++x )
00175 {
00176 (v = rowStart) += threadParameters->m_HashX[x];
00177 if ( target->ProbeData( value, dataPtr, v ) )
00178 {
00179 *wptr = value;
00180 }
00181 else
00182 {
00183 *wptr = backgroundValue;
00184 }
00185
00186 ++wptr;
00187 }
00188 }
00189 }
00190 }
00191
00193 static void InterpolateImageProbabilisticThread( void *const args, const size_t taskIdx, const size_t taskCnt, const size_t, const size_t )
00194 {
00195 InterpolateImageThreadParameters* threadParameters = static_cast<InterpolateImageThreadParameters*>( args );
00196
00197 const Self* This = threadParameters->thisObject;
00198 const size_t idx = threadParameters->m_Idx;
00199 byte* destination = threadParameters->m_Destination;
00200
00201 const AffineXform* xform = This->GetXformByIndex( idx );
00202 const UniformVolume* target = This->m_ImageVector[idx];
00203
00204 const byte paddingValue = This->m_PaddingValue;
00205 const byte backgroundValue = This->m_UserBackgroundFlag ? This->m_PrivateUserBackgroundValue : paddingValue;
00206
00207 UniformVolume::CoordinateVectorType v;
00208 byte value;
00209 const byte* dataPtr = static_cast<const byte*>( target->GetData()->GetDataPtr() );
00210
00211 const size_t startIdx = taskIdx * (This->m_ProbabilisticSamples.size() / taskCnt);
00212 const size_t endIdx = ( taskIdx == (taskCnt-1) ) ? This->m_ProbabilisticSamples.size() : (taskIdx+1) * (This->m_ProbabilisticSamples.size() / taskCnt);
00213
00214 byte *wptr = destination + startIdx;
00215 for ( size_t i = startIdx; i < endIdx; ++i, ++wptr )
00216 {
00217 const size_t offset = This->m_ProbabilisticSamples[i];
00218 v = This->m_TemplateGrid->GetGridLocation( offset );
00219 xform->ApplyInPlace( v );
00220
00221 if ( target->ProbeData( value, dataPtr, v ) )
00222 {
00223 *wptr = value;
00224 }
00225 else
00226 {
00227 *wptr = backgroundValue;
00228 }
00229 }
00230 }
00231
00232 private:
00234 class InterpolateImageThreadParameters :
00236 public ThreadParameters<Self>
00237 {
00238 public:
00240 size_t m_Idx;
00241
00243 byte* m_Destination;
00244
00245 const Vector3D* m_HashX;
00246 const Vector3D* m_HashY;
00247 const Vector3D* m_HashZ;
00248 };
00249
00250 friend ClassStream& operator<<( ClassStream& stream, const GroupwiseRegistrationFunctionalXformTemplate<AffineXform>& func );
00251 friend ClassStream& operator>>( ClassStream& stream, GroupwiseRegistrationFunctionalXformTemplate<AffineXform>& func );
00252 };
00253
00254 ClassStream& operator<<( ClassStream& stream, const GroupwiseRegistrationFunctionalXformTemplate<AffineXform>& func );
00255 ClassStream& operator>>( ClassStream& stream, GroupwiseRegistrationFunctionalXformTemplate<AffineXform>& func );
00256
00257 }
00258
00259 #endif // #ifndef __cmtkGroupwiseRegistrationFunctionalXformTemplate_Affine_h_included_