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 <Registration/cmtkImagePairSimilarityJointHistogram.h>
00034
00035 namespace
00036 cmtk
00037 {
00038
00041
00042 ImagePairSimilarityJointHistogram::ImagePairSimilarityJointHistogram
00043 ( UniformVolume::SmartConstPtr& refVolume, UniformVolume::SmartConstPtr& fltVolume, const Interpolators::InterpolationEnum interpolation )
00044 : ImagePairSimilarityMeasure( Self::PrescaleData( refVolume, &this->m_NumberOfBinsX, &this->m_ScaleFactorReference, &this->m_ScaleOffsetReference ),
00045 Self::PrescaleData( fltVolume, &this->m_NumberOfBinsY, &this->m_ScaleFactorFloating, &this->m_ScaleOffsetFloating ), interpolation )
00046 {
00047 this->m_JointHistogram.Resize( this->m_NumberOfBinsX, this->m_NumberOfBinsY );
00048 }
00049
00050 void
00051 ImagePairSimilarityJointHistogram::SetReferenceVolume( const UniformVolume::SmartConstPtr& refVolume )
00052 {
00053 Superclass::SetReferenceVolume( Self::PrescaleData( refVolume, &this->m_NumberOfBinsX, &this->m_ScaleFactorReference, &this->m_ScaleOffsetReference ) );
00054 this->m_JointHistogram.Resize( this->m_NumberOfBinsX, this->m_NumberOfBinsY );
00055 }
00056
00057 void
00058 ImagePairSimilarityJointHistogram::SetFloatingVolume( const UniformVolume::SmartConstPtr& fltVolume )
00059 {
00060 Superclass::SetFloatingVolume( Self::PrescaleData( fltVolume, &this->m_NumberOfBinsY, &this->m_ScaleFactorFloating, &this->m_ScaleOffsetFloating ) );
00061 this->m_JointHistogram.Resize( this->m_NumberOfBinsX, this->m_NumberOfBinsY );
00062 }
00063
00064 UniformVolume::SmartPtr
00065 ImagePairSimilarityJointHistogram::PrescaleData
00066 ( const UniformVolume::SmartConstPtr& volume, size_t* numberOfBins, Types::DataItem* scaleFactor, Types::DataItem* scaleOffset )
00067 {
00068 UniformVolume::SmartPtr newVolume( volume->CloneGrid() );
00069 newVolume->CreateDataArray( TYPE_ITEM );
00070 const size_t numberOfPixels = volume->GetNumberOfPixels();
00071
00072 Types::DataItem value = 0;
00073 Types::DataItem minValue = FLT_MAX;
00074 Types::DataItem maxValue = -FLT_MAX;
00075
00076 const DataGrid::IndexType& cropFrom = volume->CropRegion().From();
00077 const DataGrid::IndexType& cropTo = volume->CropRegion().To();
00078 const DataGrid::IndexType increments = volume->GetCropRegionIncrements();
00079
00080 int offset = increments[0];
00081 for ( int z = cropFrom[2]; z < cropTo[2]; ++z, offset += increments[2] )
00082 {
00083 for ( int y = cropFrom[1]; y < cropTo[1]; ++y, offset += increments[1] )
00084 {
00085 for ( int x = cropFrom[0]; x < cropTo[0]; ++x, ++offset )
00086 {
00087 if ( volume->GetDataAt( value, offset ) )
00088 {
00089 if ( value > maxValue ) maxValue = value;
00090 if ( value < minValue ) minValue = value;
00091 }
00092 }
00093 }
00094 }
00095
00096 switch ( volume->GetData()->GetDataClass() )
00097 {
00098 case DATACLASS_LABEL:
00099 {
00100 *numberOfBins = 1 + static_cast<unsigned int>(maxValue-minValue);
00101 if ( *numberOfBins > 254 )
00102 {
00103 StdErr << "Fatal error: Cannot handle more than 254 different labels.\n";
00104 exit( 1 );
00105 }
00106
00107 *scaleOffset = -minValue;
00108 *scaleFactor = 1.0;
00109
00110 for ( size_t idx = 0; idx < numberOfPixels; ++idx )
00111 {
00112 if ( volume->GetDataAt( value, idx ) )
00113 newVolume->SetDataAt( static_cast<Types::DataItem>( value + *scaleOffset ), idx );
00114 else
00115 newVolume->GetData()->SetPaddingAt( idx );
00116 }
00117 }
00118 break;
00119 default:
00120 case DATACLASS_GREY:
00121 {
00122 *numberOfBins = JointHistogramBase::CalcNumBins( volume );
00123
00124 *scaleFactor = (*numberOfBins-1) / ( maxValue - minValue );
00125 *scaleOffset = -minValue * *scaleFactor;
00126
00127 for ( size_t idx = 0; idx < numberOfPixels; ++idx )
00128 {
00129 if ( volume->GetDataAt( value, idx ) )
00130 {
00131 value = std::max( std::min( value, maxValue ), minValue );
00132 newVolume->SetDataAt( static_cast<Types::DataItem>( floor(*scaleFactor*value+*scaleOffset) ), idx );
00133 }
00134 else
00135 {
00136 newVolume->GetData()->SetPaddingAt( idx );
00137 }
00138 }
00139 }
00140 break;
00141 }
00142
00143 return newVolume;
00144 }
00145
00146 }