cmtkVoxelMatchingMetric_Type.cxx

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: 2398 $
00026 //
00027 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #include "cmtkVoxelMatchingMetric_Type.h"
00034 
00035 #include <Base/cmtkJointHistogram.h>
00036 
00037 namespace
00038 cmtk
00039 {
00040 
00043 
00044 template<class T,ScalarDataType DT>
00045 void
00046 VoxelMatchingMetric_Type<T,DT>::ImageData::Init
00047 ( const UniformVolume* volume )
00048 {
00049   const TypedArray *srcArray = volume->GetData();
00050   DataArray = TypedArray::SmartPtr( srcArray->Convert( DT ) );
00051   Data = static_cast<T*>( DataArray->GetDataPtr() );
00052   NumberOfSamples = this->DataArray->GetDataSize();
00053 
00054   this->m_ValueRange = DataArray->GetRange();
00055   BinOffset = this->m_ValueRange.m_LowerBound;
00056   BinWidth = 1;
00057 
00058   if ( srcArray->GetPaddingFlag() )
00059     {
00060     Padding = NumericTraits<T>::ConvertFromDataItem( srcArray->GetPaddingValue() );
00061     }
00062   else
00063     {
00064     Padding = NumericTraits<T>::DefaultPaddingValue;
00065     }
00066 }
00067 
00068 template<class T,ScalarDataType DT>
00069 size_t
00070 VoxelMatchingMetric_Type<T,DT>::ImageData::Init
00071 ( const UniformVolume* volume, const size_t defNumBins, const Types::DataItemRange& bounds )
00072 {
00073   const TypedArray* data = volume->GetData();
00074   this->AllocDataArray( data );
00075   
00076   Types::DataItem value = 0, minValue = FLT_MAX, maxValue = -FLT_MAX;
00077 
00078   const DataGrid::IndexType cropFrom = volume->CropRegion().From();
00079   const DataGrid::IndexType cropTo = volume->CropRegion().To();
00080   const DataGrid::IndexType increments = volume->GetCropRegionIncrements();
00081 
00082   int offset = increments[0];
00083   for ( int z = cropFrom[2]; z < cropTo[2]; ++z, offset += increments[2] ) 
00084     {
00085     for ( int y = cropFrom[1]; y < cropTo[1]; ++y, offset += increments[1] ) 
00086       {
00087       for ( int x = cropFrom[0]; x < cropTo[0]; ++x, ++offset ) 
00088         {
00089         if ( data->Get( value, offset ) ) 
00090           {
00091           if ( value > maxValue ) maxValue = value;
00092           if ( value < minValue ) minValue = value;
00093           }
00094         }
00095       }
00096     }
00097   
00098   minValue = std::max( minValue, bounds.m_LowerBound );
00099   maxValue = std::min( maxValue, bounds.m_UpperBound );
00100   
00101   unsigned int defaultValue = 0;
00102   unsigned int numBins = defNumBins;
00103 
00104   if ( numBins != CMTK_HISTOGRAM_AUTOBINS ) 
00105     {
00106     BinOffset = minValue;
00107     BinWidth = ( maxValue - minValue ) / (numBins-1);
00108     double factor = 1.0 / BinWidth;
00109     
00110     for ( size_t idx = 0; idx < NumberOfSamples; ++idx ) 
00111       {
00112       if ( data->Get( value, idx ) ) 
00113         {
00114         value = std::max( std::min( value, maxValue ), minValue );
00115         Data[idx] = static_cast<T>( floor(factor * (value-BinOffset)) );
00116         } 
00117       else 
00118         {
00119         // point to extra bins at the end of each row/column for NULL data.
00120         Data[idx] = defaultValue;
00121         }
00122       }
00123     } 
00124   else 
00125     {
00126     switch ( data->GetDataClass() ) 
00127       {
00128       case DATACLASS_LABEL: 
00129       {
00130       numBins = 1 + static_cast<unsigned int>(maxValue-minValue);
00131       if ( numBins > 254 ) 
00132         {
00133         fprintf( stderr, "Fatal error: Cannot handle more than 254 different labels.\n" );
00134         exit( 1 );
00135         }
00136       
00137       BinOffset = 0;
00138       BinWidth = 1;
00139       
00140       for ( size_t idx = 0; idx < NumberOfSamples; ++idx ) 
00141         {
00142         if ( data->Get( value, idx ) )
00143           Data[idx] = static_cast<T>( value - minValue );
00144         else
00145           // point to extra bins at the end of each row/column for NULL data.
00146           Data[idx] = defaultValue;
00147         }
00148       }
00149       break;
00150       default: // Handle everything else as grey-level data.
00151       case DATACLASS_GREY: 
00152       {
00153       numBins = JointHistogramBase::CalcNumBins( volume );
00154       BinOffset = minValue;
00155       BinWidth = ( maxValue - minValue ) / (numBins-1);
00156       double factor = 1.0 / BinWidth;
00157       
00158       for ( size_t idx = 0; idx < NumberOfSamples; ++idx ) 
00159         {
00160         if ( data->Get( value, idx ) ) 
00161           {
00162           value = std::max( std::min( value, maxValue ), minValue );
00163           Data[idx] = static_cast<T>( floor(factor*(value-BinOffset)) );
00164           } 
00165         else 
00166           {
00167           // point to extra bins at the end of each row/column for NULL data.
00168           Data[idx] = defaultValue;
00169           }
00170         }
00171       }
00172       break;
00173       } 
00174     }
00175   
00176   this->m_ValueRange = Types::DataItemRange( 0, static_cast<Types::DataItem>( numBins - 1 ) );
00177   
00178   return (Padding = numBins);
00179 }
00180 
00181 template<class T,ScalarDataType DT>
00182 void
00183 VoxelMatchingMetric_Type<T,DT>::ImageData::AllocDataArray
00184 ( const TypedArray* templateArray )
00185 {
00186   NumberOfSamples = templateArray->GetDataSize();
00187   DataArray = TypedArray::SmartPtr( TypedArray::Create( DT, NumberOfSamples ) );
00188   Data = static_cast<T*>( DataArray->GetDataPtr() );
00189 }
00190 
00191 template<class T,ScalarDataType DT>
00192 void
00193 VoxelMatchingMetric_Type<T,DT>::ImageData::PrecomputeIncrements
00194 ( const UniformVolume* volume )
00195 {
00196   this->ImageDims = volume->GetDims();
00197   // pre-compute relative offsets for tri-linear model interpolation
00198   nextJ = volume->GetDims()[0];
00199   nextK = nextJ * volume->GetDims()[1];
00200   nextIJ = nextJ + 1;
00201   nextIK = nextK + 1;
00202   nextJK = nextK + nextJ;
00203   nextIJK = nextJK + 1;
00204 }
00205 
00206 // instantiate necessary templates.
00207 template class VoxelMatchingMetric_Type<byte,TYPE_BYTE>;
00208 template class VoxelMatchingMetric_Type<short,TYPE_SHORT>;
00209 
00210 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines