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 namespace
00034 cmtk
00035 {
00036 
00039 
00040 UniformVolume* 
00041 ReformatVolume::GetTransformedReference
00042 ( const std::vector<SplineWarpXform::SmartPtr>* xformList,
00043   std::vector<UniformVolume::SmartPtr>* volumeList,
00044   Types::Coordinate *const volumeOffset,
00045   const bool includeReferenceData )
00046 {
00047   UniformVolume* result = NULL;
00048   unsigned int numberOfImages = 0;
00049 
00050   std::vector<UniformVolumeInterpolatorBase::SmartConstPtr> interpolatorList;
00051   interpolatorList.push_back( this->CreateInterpolator( this->ReferenceVolume ) );
00052   if ( volumeList )
00053     {
00054     numberOfImages = 1 + volumeList->size();
00055     for ( unsigned int img = 0; img < numberOfImages-1; ++img ) 
00056       {
00057       interpolatorList.push_back( this->CreateInterpolator( (*volumeList)[img] ) );
00058       }
00059     }
00060   
00061   const SplineWarpXform* splineXform = dynamic_cast<const SplineWarpXform*>( this->m_WarpXform.GetConstPtr() );
00062   if ( ! splineXform ) 
00063     {
00064     StdErr << "ERROR: ReformatVolume::GetTransformedReference supports spline warp only.\n";
00065     return NULL;
00066     }
00067   
00068   DataClass dataClass = ReferenceVolume->GetData()->GetDataClass();
00069   int maxLabel = 0;
00070   if ( dataClass == DATACLASS_LABEL ) 
00071     {
00072     const Types::DataItemRange rangeRef = ReferenceVolume->GetData()->GetRange();
00073     maxLabel = static_cast<int>( rangeRef.m_UpperBound );
00074     
00075     for ( unsigned int img = 0; img < numberOfImages-1; ++img ) 
00076       {
00077       const Types::DataItemRange rangeFlt = (*volumeList)[img]->GetData()->GetRange();
00078       maxLabel = std::max( maxLabel, static_cast<int>( rangeFlt.m_UpperBound ) );
00079       }
00080     }
00081   
00082   
00083   Types::Coordinate bbFrom[3], delta[3];
00084   result = this->CreateTransformedReference( bbFrom, delta, volumeOffset );
00085 
00086   const ScalarDataType dtype = (this->m_UserDataType != TYPE_NONE) ? this->m_UserDataType : ReferenceVolume->GetData()->GetType();
00087   TypedArray::SmartPtr dataArray( TypedArray::Create( dtype, result->GetNumberOfPixels() ) );
00088   if ( this->m_UsePaddingValue )
00089     dataArray->SetPaddingValue( this->m_PaddingValue );
00090   result->SetData( dataArray );
00091 
00092   const size_t numberOfThreads = Threads::GetNumberOfThreads();
00093   std::vector<GetTransformedReferenceTP> params( numberOfThreads );
00094 
00095   for ( size_t thr = 0; thr < numberOfThreads; ++thr ) 
00096     {
00097     params[thr].thisObject = this;
00098     params[thr].ThisThreadIndex = thr;
00099     params[thr].NumberOfThreads = numberOfThreads;
00100     params[thr].dims = result->GetDims();
00101     params[thr].bbFrom = bbFrom;
00102     params[thr].delta = delta;
00103     params[thr].splineXform = splineXform;
00104     params[thr].numberOfImages = numberOfImages;
00105     params[thr].xformList = xformList;
00106     params[thr].volumeList = volumeList;
00107     params[thr].interpolatorList = &interpolatorList;
00108     params[thr].dataArray = dataArray;
00109     params[thr].maxLabel = maxLabel;
00110     params[thr].IncludeReferenceData = includeReferenceData;
00111     }
00112   
00113   switch ( dataClass ) 
00114     {
00115     default:
00116     case DATACLASS_GREY: 
00117     {
00118     if ( xformList && !xformList->empty() )
00119       Threads::RunThreads( GetTransformedReferenceGreyAvg, numberOfThreads, ¶ms[0] );
00120     else
00121       Threads::RunThreads( GetTransformedReferenceGrey, numberOfThreads, ¶ms[0] );
00122     }
00123     break;
00124     case DATACLASS_LABEL: 
00125     {
00126     Threads::RunThreads( GetTransformedReferenceLabel, numberOfThreads, ¶ms[0] );
00127     }
00128     break;
00129     }
00130 
00131   return result;
00132 }
00133 
00134 CMTK_THREAD_RETURN_TYPE
00135 ReformatVolume::GetTransformedReferenceGreyAvg( void *const arg )
00136 {
00137   GetTransformedReferenceTP* params = static_cast<GetTransformedReferenceTP*>( arg );
00138 
00139   TypedArray::SmartPtr dataArray = params->dataArray;
00140   const SplineWarpXform* splineXform = params->splineXform;
00141   const Types::Coordinate* delta = params->delta;
00142   const Types::Coordinate* bbFrom = params->bbFrom;
00143   const DataGrid::IndexType& dims = params->dims;
00144 
00145   const std::vector<SplineWarpXform::SmartPtr>* xformList = params->xformList;
00146   const std::vector<UniformVolumeInterpolatorBase::SmartConstPtr>* interpolatorList = params->interpolatorList;
00147 
00148   Types::Coordinate minDelta = std::min( delta[0], std::min( delta[1], delta[2] ) );
00149   
00150   std::vector<Types::DataItem> value( params->numberOfImages );
00151   
00152   std::vector<const SplineWarpXform*> xforms( params->numberOfImages-1 );
00153 
00154   for ( unsigned int img = 0; img < params->numberOfImages-1; ++img ) 
00155     {
00156     xforms[img] = (*xformList)[img];
00157     }
00158 
00159   int cx = params->ThisThreadIndex % dims[0];
00160   int cy = (params->ThisThreadIndex / dims[0]) % dims[1];
00161   int cz = params->ThisThreadIndex / (dims[0] * dims[1]) ;
00162 
00163   UniformVolume::CoordinateVectorType xyz;
00164   xyz[0] = bbFrom[0] + cx * delta[0];
00165   xyz[1] = bbFrom[1] + cy * delta[1];
00166   xyz[2] = bbFrom[2] + cz * delta[2];
00167   
00168   const size_t numberOfPixels = dims[0] * dims[1] * dims[2];
00169   const size_t statusUpdateIncrement = std::max<size_t>( 1, numberOfPixels / 100 );
00170 
00171   UniformVolume::CoordinateVectorType u, v;
00172   for ( size_t offset = params->ThisThreadIndex; offset < numberOfPixels; offset += params->NumberOfThreads ) 
00173     {
00174     if ( ! params->ThisThreadIndex && ! (offset % statusUpdateIncrement) ) 
00175       Progress::SetProgress( offset );
00176 
00177     v = xyz;
00178     const bool success = splineXform->ApplyInverseInPlace( v, 0.1 * minDelta );
00179     u = v;
00180     
00181     unsigned int toIdx = 0;
00182     if ( success ) 
00183       {
00184       if ( params->IncludeReferenceData ) 
00185         {
00186         if ( (*interpolatorList)[0]->GetDataAt( v, value[toIdx] ) )
00187           ++toIdx;
00188         }
00189       
00190       for ( unsigned int img = 0; img < params->numberOfImages-1; ++img ) 
00191         {
00192         v = u;
00193         xforms[img]->ApplyInPlace( v );
00194         
00195         if ( (*interpolatorList)[img+1]->GetDataAt( v, value[toIdx] ) )
00196           ++toIdx;
00197         }
00198       }
00199     if ( toIdx && success ) 
00200       {
00201       Types::DataItem avg = value[0];
00202       for ( unsigned int idx = 1; idx < toIdx; ++idx )
00203         avg += value[idx];
00204       dataArray->Set( avg / toIdx, offset );
00205       } 
00206     else
00207       dataArray->SetPaddingAt( offset );
00208 
00209     cx += params->NumberOfThreads;
00210     if ( cx >= dims[0] )
00211       {
00212       cy += cx / dims[0];
00213       cx %= dims[0];
00214 
00215       if ( cy >= dims[1] )
00216         {
00217         cz += cy / dims[1];
00218         cy %= dims[1];
00219         xyz[2] = bbFrom[2] + cz * delta[2];
00220         }
00221       xyz[1] = bbFrom[1] + cy * delta[1];
00222       }
00223     xyz[0] = bbFrom[0] + cx * delta[0];
00224     }
00225 
00226   return CMTK_THREAD_RETURN_VALUE;
00227 }
00228 
00229 }