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 "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
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
00146 Data[idx] = defaultValue;
00147 }
00148 }
00149 break;
00150 default:
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
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
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
00207 template class VoxelMatchingMetric_Type<byte,TYPE_BYTE>;
00208 template class VoxelMatchingMetric_Type<short,TYPE_SHORT>;
00209
00210 }