cmtkImagePairNonrigidRegistrationFunctionalTemplate.txx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2660 $
00026 //
00027 //  $LastChangedDate: 2010-12-14 12:35:50 -0800 (Tue, 14 Dec 2010) $
00028 //
00029 //  $LastChangedBy: torsten_at_home $
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 /*freeArray*/, true /*padding*/, &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       // We cannot use the precomputed table of VOIs here because in "fast"
00135       // mode, these VOIs are smaller than we want them here.
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             // Continue metric computation.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines