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
00034
00035 #include <Registration/cmtkGroupwiseRegistrationFunctionalXformTemplate.h>
00036
00037 #include <Base/cmtkMathUtil.h>
00038 #include <IO/cmtkVolumeIO.h>
00039
00040 #ifdef CMTK_BUILD_MPI
00041 # include <mpi.h>
00042 # include <IO/cmtkMPI.h>
00043 #endif
00044
00045 namespace
00046 cmtk
00047 {
00048
00051
00052 template<class TXform>
00053 GroupwiseRegistrationFunctionalXformTemplate<TXform>::GroupwiseRegistrationFunctionalXformTemplate()
00054 {
00055
00056 this->m_InterpolateTaskInfo.resize( 4 * ThreadPool::GetGlobalThreadPool().GetNumberOfThreads() );
00057 }
00058
00059 template<class TXform>
00060 void
00061 GroupwiseRegistrationFunctionalXformTemplate<TXform>
00062 ::InterpolateImage
00063 ( const size_t idx, byte* const destination )
00064 {
00065 for ( size_t task = 0; task < this->m_InterpolateTaskInfo.size(); ++task )
00066 {
00067 this->m_InterpolateTaskInfo[task].thisObject = this;
00068 this->m_InterpolateTaskInfo[task].m_Idx = idx;
00069 this->m_InterpolateTaskInfo[task].m_Destination = destination;
00070 }
00071
00072 ThreadPool& threadPool = ThreadPool::GetGlobalThreadPool();
00073 if ( this->m_ProbabilisticSamples.size() )
00074 threadPool.Run( InterpolateImageProbabilisticThread, this->m_InterpolateTaskInfo );
00075 else
00076 threadPool.Run( InterpolateImageThread, this->m_InterpolateTaskInfo );
00077
00078
00079 size_t numberOfOutsidePixels = 0;
00080 for ( size_t task = 0; task < this->m_InterpolateTaskInfo.size(); ++task )
00081 {
00082 numberOfOutsidePixels += this->m_InterpolateTaskInfo[task].m_NumberOfOutsidePixels;
00083 }
00084
00085
00086 if ( numberOfOutsidePixels > static_cast<size_t>( this->m_MaxRelativeNumberOutsidePixels * this->m_TemplateNumberOfSamples ) )
00087 {
00088 throw typename Self::BadXform();
00089 }
00090 }
00091
00092 template<class TXform>
00093 void
00094 GroupwiseRegistrationFunctionalXformTemplate<TXform>::InterpolateImageThread
00095 ( void *const args, const size_t taskIdx, const size_t taskCnt, const size_t, const size_t )
00096 {
00097 InterpolateImageThreadParameters* threadParameters = static_cast<InterpolateImageThreadParameters*>( args );
00098
00099 const Self* This = threadParameters->thisObject;
00100 const size_t idx = threadParameters->m_Idx;
00101 byte* destination = threadParameters->m_Destination;
00102
00103 const TXform* xform = This->GetXformByIndex(idx);
00104 const UniformVolume* target = This->m_ImageVector[idx];
00105
00106 const byte paddingValue = This->m_PaddingValue;
00107 const byte backgroundValue = This->m_UserBackgroundFlag ? This->m_PrivateUserBackgroundValue : paddingValue;
00108 threadParameters->m_NumberOfOutsidePixels = 0;
00109
00110 Vector3D v;
00111 byte value;
00112 const byte* dataPtr = static_cast<const byte*>( target->GetData()->GetDataPtr() );
00113
00114 const int dimsX = This->m_TemplateGrid->GetDims()[AXIS_X];
00115 const int dimsY = This->m_TemplateGrid->GetDims()[AXIS_Y];
00116 const int dimsZ = This->m_TemplateGrid->GetDims()[AXIS_Z];
00117
00118 for ( int z = taskIdx; (z < dimsZ); z += taskCnt )
00119 {
00120 byte *wptr = destination + z * dimsX * dimsY;
00121 for ( int y = 0; (y < dimsY); ++y )
00122 {
00123 for ( int x = 0; x < dimsX; ++x )
00124 {
00125 This->m_TemplateGrid->GetGridLocation( v, x, y, z );
00126 xform->ApplyInPlace( v );
00127
00128 if ( target->ProbeData( value, dataPtr, v ) )
00129 {
00130 *wptr = value;
00131 }
00132 else
00133 {
00134 *wptr = backgroundValue;
00135 ++threadParameters->m_NumberOfOutsidePixels;
00136 }
00137
00138 ++wptr;
00139 }
00140 }
00141 }
00142 }
00143
00144 template<class TXform>
00145 void
00146 GroupwiseRegistrationFunctionalXformTemplate<TXform>::InterpolateImageProbabilisticThread
00147 ( void *const args, const size_t taskIdx, const size_t taskCnt, const size_t, const size_t )
00148 {
00149 InterpolateImageThreadParameters* threadParameters = static_cast<InterpolateImageThreadParameters*>( args );
00150
00151 const Self* This = threadParameters->thisObject;
00152 const size_t idx = threadParameters->m_Idx;
00153 byte* destination = threadParameters->m_Destination;
00154 threadParameters->m_NumberOfOutsidePixels = 0;
00155
00156 const TXform* xform = This->GetXformByIndex(idx);
00157 const UniformVolume* target = This->m_ImageVector[idx];
00158
00159 const byte paddingValue = This->m_PaddingValue;
00160 const byte backgroundValue = This->m_UserBackgroundFlag ? This->m_PrivateUserBackgroundValue : paddingValue;
00161
00162 Vector3D v;
00163 byte value;
00164 const byte* dataPtr = static_cast<const byte*>( target->GetData()->GetDataPtr() );
00165
00166 const size_t startIdx = taskIdx * (This->m_ProbabilisticSamples.size() / taskCnt);
00167 const size_t endIdx = ( taskIdx == taskCnt ) ? This->m_ProbabilisticSamples.size() : (taskIdx+1) * (This->m_ProbabilisticSamples.size() / taskCnt);
00168
00169 byte *wptr = destination + startIdx;
00170 for ( size_t i = startIdx; i < endIdx; ++i, ++wptr )
00171 {
00172 const size_t offset = This->m_ProbabilisticSamples[i];
00173 This->m_TemplateGrid->GetGridLocation( v, offset );
00174 xform->ApplyInPlace( v );
00175
00176 if ( target->ProbeData( value, dataPtr, v ) )
00177 {
00178 *wptr = value;
00179 }
00180 else
00181 {
00182 *wptr = backgroundValue;
00183 ++threadParameters->m_NumberOfOutsidePixels;
00184 }
00185 }
00186 }
00187
00189
00190 }