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 #ifndef __cmtkImagePairAffineRegistrationFunctional_h_included_
00034 #define __cmtkImagePairAffineRegistrationFunctional_h_included_
00035
00036 #include <cmtkconfig.h>
00037
00038 #include <Registration/cmtkImagePairRegistrationFunctional.h>
00039
00040 #include <Base/cmtkVector.h>
00041 #include <Base/cmtkAffineXform.h>
00042 #include <Base/cmtkVolume.h>
00043 #include <Base/cmtkUniformVolume.h>
00044 #include <Base/cmtkMathUtil.h>
00045 #include <Base/cmtkTypes.h>
00046 #include <Base/cmtkVolumeClipping.h>
00047
00048 #include <System/cmtkException.h>
00049 #include <System/cmtkThreadPool.h>
00050
00051 #include <cassert>
00052
00053 namespace
00054 cmtk
00055 {
00056
00059
00062 class ImagePairAffineRegistrationFunctional :
00064 public ImagePairRegistrationFunctional
00065 {
00066 public:
00068 typedef ImagePairAffineRegistrationFunctional Self;
00069
00071 typedef ImagePairRegistrationFunctional Superclass;
00072
00074 typedef SmartPointer<Self> SmartPtr;
00075
00077 virtual void GetParamVector ( CoordinateVector& v )
00078 {
00079 this->m_AffineXform->GetParamVector( v );
00080 }
00081
00083 virtual Types::Coordinate GetParamStep( const size_t idx, const Types::Coordinate mmStep = 1 ) const
00084 {
00085 return this->m_AffineXform->GetParamStep( idx, this->m_FloatingSize, mmStep );
00086 }
00087
00089 virtual size_t ParamVectorDim() const
00090 {
00091 return this->m_AffineXform->ParamVectorDim();
00092 }
00093
00095 virtual size_t VariableParamVectorDim() const
00096 {
00097 return this->m_AffineXform->VariableParamVectorDim();
00098 }
00099
00100 protected:
00102 AffineXform::SmartPtr m_AffineXform;
00103
00105 VolumeClipping Clipper;
00106
00123 int ClipZ ( const VolumeClipping& clipper, const Vector3D& origin, DataGrid::IndexType::ValueType& start, DataGrid::IndexType::ValueType &end ) const
00124 {
00125
00126 Types::Coordinate fromFactor, toFactor;
00127 if (! clipper.ClipZ( fromFactor, toFactor, origin ) )
00128 return 0;
00129
00130
00131 start = static_cast<DataGrid::IndexType::ValueType>( (this->m_ReferenceDims[2]-1)*fromFactor );
00132 end = 1+std::min( (int)(this->m_ReferenceDims[2]-1), (int)(1 + ((this->m_ReferenceDims[2]-1)*toFactor) ) );
00133
00134
00135 start = std::max<DataGrid::IndexType::ValueType>( start, this->m_ReferenceCropRegion.From()[2] );
00136 end = std::min<DataGrid::IndexType::ValueType>( end, this->m_ReferenceCropRegion.To()[2] );
00137
00138
00139 return (start < end );
00140 }
00141
00168 int ClipX ( const VolumeClipping& clipper, const Vector3D& origin, DataGrid::IndexType::ValueType& start, DataGrid::IndexType::ValueType &end ) const
00169 {
00170
00171 Types::Coordinate fromFactor, toFactor;
00172 if ( ! clipper.ClipX( fromFactor, toFactor, origin, 0, 2, false, true ) )
00173 return 0;
00174
00175 fromFactor = std::min<Types::Coordinate>( 1.0, fromFactor );
00176
00177
00178 start = std::max( 0, (int)((this->m_ReferenceDims[0]-1)*fromFactor)-1 );
00179 while ( ( start*this->m_ReferenceGrid->m_Delta[0] < fromFactor*this->m_ReferenceSize[0]) && ( start < this->m_ReferenceDims[0] ) )
00180 ++start;
00181
00182 if ( (toFactor > 1.0) || (start == this->m_ReferenceDims[0]) )
00183 {
00184 end = this->m_ReferenceDims[0];
00185 }
00186 else
00187 {
00188 end = std::min( this->m_ReferenceDims[0]-2, (int)(1 + (this->m_ReferenceDims[0]-1)*toFactor));
00189 while ( end*this->m_ReferenceGrid->m_Delta[0] > toFactor*this->m_ReferenceSize[0] )
00190 --end;
00191 ++end;
00192 }
00193
00194
00195 start = std::max<DataGrid::IndexType::ValueType>( start, this->m_ReferenceCropRegion.From()[0] );
00196 end = std::min<DataGrid::IndexType::ValueType>( end, this->m_ReferenceCropRegion.To()[0] );
00197
00198
00199 return (start < end );
00200 }
00201
00218 int ClipY ( const VolumeClipping& clipper, const Vector3D& origin, DataGrid::IndexType::ValueType& start, DataGrid::IndexType::ValueType &end ) const
00219 {
00220
00221 Types::Coordinate fromFactor, toFactor;
00222 if ( !clipper.ClipY( fromFactor, toFactor, origin ) )
00223 return 0;
00224
00225
00226 start = static_cast<DataGrid::IndexType::ValueType>( (this->m_ReferenceDims[1]-1)*fromFactor );
00227
00228 if ( toFactor > 1.0 )
00229 {
00230 end = this->m_ReferenceDims[1];
00231 }
00232 else
00233 {
00234 end = 1+std::min( this->m_ReferenceDims[1]-1, (int)(1+(this->m_ReferenceDims[1]-1)*toFactor ) );
00235 }
00236
00237 start = std::max<DataGrid::IndexType::ValueType>( start, this->m_ReferenceCropRegion.From()[1] );
00238 end = std::min<DataGrid::IndexType::ValueType>( end, this->m_ReferenceCropRegion.To()[1] );
00239
00240
00241 return (start < end );
00242 }
00243
00244 public:
00246 ImagePairAffineRegistrationFunctional( UniformVolume::SmartPtr refVolume, UniformVolume::SmartPtr modVolume, AffineXform::SmartPtr& affineXform )
00247 : ImagePairRegistrationFunctional( refVolume, modVolume ),
00248 m_AffineXform( affineXform )
00249 {}
00250
00252 virtual ~ImagePairAffineRegistrationFunctional() {}
00253
00260 static ImagePairAffineRegistrationFunctional* Create( const int metric,
00261 UniformVolume::SmartPtr& refVolume,
00262 UniformVolume::SmartPtr& fltVolume,
00263 const Interpolators::InterpolationEnum interpolation,
00264 AffineXform::SmartPtr& affineXform
00265 );
00266 };
00267
00269
00270 }
00271
00272 #endif // #ifndef __cmtkImagePairAffineRegistrationFunctional_h_included_