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 <algorithm>
00034
00035 #include "cmtkInverseInterpolationVolumeReconstructionBase.h"
00036
00037 #include <Base/cmtkHistogramBase.h>
00038 #include <System/cmtkProgress.h>
00039
00040 namespace
00041 cmtk
00042 {
00043
00044 InverseInterpolationVolumeReconstructionBase
00045 ::InverseInterpolationVolumeReconstructionBase( const UniformVolume* originalImage, const int interleaveFactor, const int interleaveAxis )
00046 : VolumeInjectionReconstruction( originalImage, interleaveFactor, interleaveAxis ),
00047 m_RegionalIntensityTruncation( true ),
00048 m_LowestMaxError( 1e12 ),
00049 m_FourthOrderError( false ),
00050 m_ConstraintWeightLNorm( 0.0 )
00051 {
00052 }
00053
00054 InverseInterpolationVolumeReconstructionBase
00055 ::InverseInterpolationVolumeReconstructionBase( const UniformVolume* reconstructionGrid, std::vector<UniformVolume::SmartPtr>& images )
00056 : VolumeInjectionReconstruction( reconstructionGrid, images ),
00057 m_RegionalIntensityTruncation( true ),
00058 m_LowestMaxError( 1e12 ),
00059 m_FourthOrderError( false ),
00060 m_ConstraintWeightLNorm( 0.0 )
00061 {
00062 }
00063
00064 double
00065 InverseInterpolationVolumeReconstructionBase
00066 ::ComputeApproximationError()
00067 {
00068 this->m_MeanSquaredError = 0;
00069 this->m_MaximumError = 0;
00070
00071 this->m_DifferencePassImages.clear();
00072
00073 double squaredError = 0;
00074 size_t totalNumberOfPixels = 0;
00075 for ( int pass = 0; pass < this->m_NumberOfPasses; ++pass )
00076 {
00077 UniformVolume::SmartPtr differencePassImage( this->m_InterpolatedPassImages[pass]->CloneGrid());
00078 differencePassImage->CreateDataArray( TYPE_FLOAT, true );
00079
00080 const int numberOfPixels = this->m_InterpolatedPassImages[pass]->GetNumberOfPixels();
00081
00082 for ( int idx = 0; idx < numberOfPixels; ++idx )
00083 {
00084 Types::DataItem originalData, interpolatedData;
00085 this->m_OriginalPassImages[pass]->GetDataAt( originalData, idx );
00086
00087 if ( this->m_InterpolatedPassImages[pass]->GetDataAt( interpolatedData, idx ) )
00088 {
00089 const double difference = interpolatedData - originalData;
00090 differencePassImage->SetDataAt( difference, idx );
00091 if ( this->m_FourthOrderError )
00092 squaredError += difference*difference*difference*difference;
00093 else
00094 squaredError += difference*difference;
00095
00096 this->m_MaximumError = std::max<double>( fabs(difference), this->m_MaximumError );
00097 ++totalNumberOfPixels;
00098 }
00099 else
00100 {
00101 differencePassImage->GetData()->SetPaddingAt( idx );
00102 }
00103 }
00104
00105 this->m_DifferencePassImages.push_back( differencePassImage );
00106 }
00107 return (this->m_MeanSquaredError = squaredError / totalNumberOfPixels);
00108 }
00109
00110 void
00111 InverseInterpolationVolumeReconstructionBase
00112 ::Optimize( const int numberOfIterations )
00113 {
00114 const int numberOfPixels = this->m_CorrectedImage->GetNumberOfPixels();
00115 ap::real_1d_array x;
00116 x.setbounds( 1, numberOfPixels );
00117 for ( int i = 1; i <= numberOfPixels; ++i )
00118 {
00119 x(i) = this->m_CorrectedImage->GetDataAt( i-1 );
00120 }
00121
00122 const int nbdAll = this->m_RegionalIntensityTruncation ? 2 : 0;
00123 ap::integer_1d_array nbd;
00124 nbd.setbounds( 1, numberOfPixels );
00125 for ( int i = 1; i <= numberOfPixels; ++i )
00126 {
00127 nbd(i) = nbdAll;
00128 if ( this->m_NeighorhoodMinPixelValues(i) > this->m_NeighorhoodMaxPixelValues(i) )
00129 {
00130 this->m_NeighorhoodMinPixelValues(i) = this->m_OriginalImageRange.m_LowerBound;
00131 this->m_NeighorhoodMaxPixelValues(i) = this->m_OriginalImageRange.m_UpperBound;
00132 }
00133 }
00134
00135 Progress::Begin( 0, numberOfIterations, 1, "Inverse Interpolation" );
00136
00137 int info;
00138 ap::lbfgsbminimize( this->m_FunctionAndGradient, numberOfPixels, 5, x, 1e-10 , 1e-10 , 1e-10 , numberOfIterations,
00139 nbd, this->m_NeighorhoodMinPixelValues, this->m_NeighorhoodMaxPixelValues, info );
00140
00141 Progress::Done();
00142
00143 if ( info < 0 )
00144 StdErr << "ERROR: lbfgsbminimize returned status code " << info << "\n";
00145 else
00146 for ( int i = 1; i <= numberOfPixels; ++i )
00147 this->m_CorrectedImage->SetDataAt( x(i), i-1 );
00148 }
00149
00150 }
00151