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 <Base/cmtkTypedArrayFunctionHistogramMatching.h>
00034
00035 #include <vector>
00036
00037 template<class VM>
00038 void
00039 cmtk::ImagePairNonrigidRegistrationFunctionalTemplate<VM>::MatchRefFltIntensities()
00040 {
00041 const Types::DataItem paddingValue = DataTypeTraits<Types::DataItem>::ChoosePaddingValue();
00042 TypedArray::SmartPtr warpedArray( TypedArray::Create( TYPE_ITEM, this->m_WarpedVolume, this->m_FloatingGrid->GetNumberOfPixels(), false , true , &paddingValue ) );
00043
00044 UniformVolume::SmartPtr floatingCopy( this->m_FloatingGrid->Clone() );
00045 floatingCopy->GetData()->ApplyFunctionObject( TypedArrayFunctionHistogramMatching( *warpedArray, *(this->m_ReferenceGrid->GetData()) ) );
00046 this->m_Metric->SetFloatingVolume( floatingCopy );
00047 }
00048
00049 template<class VM>
00050 void
00051 cmtk::ImagePairNonrigidRegistrationFunctionalTemplate<VM>::UpdateWarpFixedParameters()
00052 {
00053 if ( !this->m_ConsistencyHistogram )
00054 {
00055 this->m_ConsistencyHistogram = JointHistogram<unsigned int>::SmartPtr( new JointHistogram<unsigned int>() );
00056 const unsigned int numSamplesX = this->m_Metric->GetNumberOfSamplesX();
00057 const Types::DataItemRange rangeX = this->m_Metric->GetDataRangeX();
00058 const unsigned int numBinsX = this->m_ConsistencyHistogram->CalcNumBins( numSamplesX, rangeX );
00059
00060 const unsigned int numSamplesY = this->m_Metric->GetNumberOfSamplesY();
00061 const Types::DataItemRange rangeY = this->m_Metric->GetDataRangeY();
00062 const unsigned int numBinsY = this->m_ConsistencyHistogram->CalcNumBins( numSamplesY, rangeY );
00063
00064 this->m_ConsistencyHistogram->Resize( numBinsX, numBinsY );
00065 this->m_ConsistencyHistogram->SetRangeX( rangeX );
00066 this->m_ConsistencyHistogram->SetRangeY( rangeY );
00067 }
00068
00069 int numCtrlPoints = this->Dim / 3;
00070
00071 std::vector<double> mapRef( numCtrlPoints );
00072 std::vector<double> mapMod( numCtrlPoints );
00073
00074 DataGrid::RegionType voi;
00075 Vector3D fromVOI, toVOI;
00076 int pX, pY, pZ;
00077
00078 int inactive = 0;
00079
00080 const Types::DataItem unsetY = DataTypeTraits<Types::DataItem>::ChoosePaddingValue();
00081
00082 if ( this->m_ReferenceDataClass == DATACLASS_LABEL )
00083 {
00084 if ( this->m_ActiveCoordinates )
00085 this->m_Warp->SetParametersActive( this->m_ActiveCoordinates );
00086 else
00087 this->m_Warp->SetParametersActive();
00088
00089 for ( int ctrl = 0; ctrl < numCtrlPoints; ++ctrl )
00090 {
00093 this->m_Warp->GetVolumeOfInfluence( 3 * ctrl, this->ReferenceFrom, this->ReferenceTo, fromVOI, toVOI, 0 );
00094 voi = this->GetReferenceGridRange( fromVOI, toVOI );
00095
00096 int r = voi.From()[0] + this->m_DimsX * ( voi.From()[1] + this->m_DimsY * voi.From()[2] );
00097
00098 bool active = false;
00099 for ( pZ = voi.From()[2]; (pZ < voi.To()[2]) && !active; ++pZ )
00100 {
00101 for ( pY = voi.From()[1]; (pY < voi.To()[1]) && !active; ++pY )
00102 {
00103 for ( pX = voi.From()[0]; (pX < voi.To()[0]); ++pX, ++r )
00104 {
00105 if ( ( this->m_Metric->GetSampleX( r ) != 0 ) || ( ( this->m_WarpedVolume[r] != unsetY ) && ( this->m_WarpedVolume[r] != 0 ) ) )
00106 {
00107 active = true;
00108 break;
00109 }
00110 }
00111 r += ( voi.From()[0] + ( this->m_DimsX-voi.To()[0] ) );
00112 }
00113 r += this->m_DimsX * ( voi.From()[1] + ( this->m_DimsY-voi.To()[1] ) );
00114 }
00115
00116 if ( !active )
00117 {
00118 inactive += 3;
00119
00120 int dim = 3 * ctrl;
00121 for ( int idx=0; idx<3; ++idx, ++dim )
00122 {
00123 this->m_Warp->SetParameterInactive( dim );
00124 }
00125 }
00126 }
00127 }
00128 else
00129 {
00130 for ( int ctrl = 0; ctrl < numCtrlPoints; ++ctrl )
00131 {
00132 this->m_ConsistencyHistogram->Reset();
00133
00134
00135
00136 this->m_Warp->GetVolumeOfInfluence( 3 * ctrl, this->ReferenceFrom, this->ReferenceTo, fromVOI, toVOI, 0 );
00137 voi = this->GetReferenceGridRange( fromVOI, toVOI );
00138
00139 int r = voi.From()[0] + this->m_DimsX * ( voi.From()[1] + this->m_DimsY * voi.From()[2] );
00140
00141 const int endOfLine = ( voi.From()[0] + ( this->m_DimsX-voi.To()[0]) );
00142 const int endOfPlane = this->m_DimsX * ( voi.From()[1] + (this->m_DimsY-voi.To()[1]) );
00143
00144 for ( pZ = voi.From()[2]; pZ<voi.To()[2]; ++pZ )
00145 {
00146 for ( pY = voi.From()[1]; pY<voi.To()[1]; ++pY )
00147 {
00148 for ( pX = voi.From()[0]; pX<voi.To()[0]; ++pX, ++r )
00149 {
00150
00151 if ( this->m_WarpedVolume[r] != unsetY )
00152 {
00153 this->m_ConsistencyHistogram->Increment( this->m_ConsistencyHistogram->ValueToBinX( this->m_Metric->GetSampleX( r ) ), this->m_ConsistencyHistogram->ValueToBinY( this->m_WarpedVolume[r] ) );
00154 }
00155 }
00156 r += endOfLine;
00157 }
00158 r += endOfPlane;
00159 }
00160 this->m_ConsistencyHistogram->GetMarginalEntropies( mapRef[ctrl], mapMod[ctrl] );
00161 }
00162
00163 double refMin = HUGE_VAL, refMax = -HUGE_VAL;
00164 double modMin = HUGE_VAL, modMax = -HUGE_VAL;
00165 for ( int ctrl=0; ctrl<numCtrlPoints; ++ctrl )
00166 {
00167 if ( mapRef[ctrl] < refMin ) refMin = mapRef[ctrl];
00168 if ( mapRef[ctrl] > refMax ) refMax = mapRef[ctrl];
00169 if ( mapMod[ctrl] < modMin ) modMin = mapMod[ctrl];
00170 if ( mapMod[ctrl] > modMax ) modMax = mapMod[ctrl];
00171 }
00172
00173 const double refThresh = refMin + this->m_AdaptiveFixThreshFactor * (refMax - refMin);
00174 const double modThresh = modMin + this->m_AdaptiveFixThreshFactor * (modMax - modMin);
00175
00176 if ( this->m_ActiveCoordinates )
00177 this->m_Warp->SetParametersActive( this->m_ActiveCoordinates );
00178 else
00179 this->m_Warp->SetParametersActive();
00180
00181 for ( int ctrl=0; ctrl<numCtrlPoints; ++ctrl )
00182 {
00183 if ( ( mapRef[ctrl] < refThresh ) && ( mapMod[ctrl] < modThresh ) )
00184 {
00185 int dim = 3 * ctrl;
00186 for ( int idx=0; idx<3; ++idx, ++dim )
00187 {
00188 this->m_Warp->SetParameterInactive( dim );
00189 }
00190 inactive += 3;
00191 }
00192 }
00193 }
00194
00195 for ( size_t idx = 0; idx < this->Dim; ++idx )
00196 {
00197 if ( this->m_Warp->GetParameterActive( idx ) )
00198 {
00199 this->m_StepScaleVector[idx] = this->GetParamStep( idx );
00200 }
00201 else
00202 {
00203 this->m_StepScaleVector[idx] = 0;
00204 }
00205 }
00206
00207 fprintf( stderr, "Deactivated %d out of %d parameters.\n", inactive, (int)this->Dim );
00208
00209 this->WarpNeedsFixUpdate = false;
00210 }
00211