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 "cmtkMakeInitialAffineTransformation.h"
00034
00035 #include <Base/cmtkAffineXform.h>
00036
00037 namespace
00038 cmtk
00039 {
00040
00043
00044 const std::string
00045 MakeInitialAffineTransformation
00046 ::GetModeName( const Self::Mode mode )
00047 {
00048 switch ( mode )
00049 {
00050 case Self::NONE:
00051 default:
00052 return std::string( "none" );
00053 case Self::FOV:
00054 return std::string( "FieldsOfView" );
00055 case Self::COM:
00056 return std::string( "CentersOfMass" );
00057 case Self::PAX:
00058 return std::string( "PrincipalAxes" );
00059 case Self::PHYS:
00060 return std::string( "PhysicalCoordinates" );
00061 }
00062 return std::string( "unknown" );
00063 }
00064
00065 AffineXform*
00066 MakeInitialAffineTransformation
00067 ::Create( const UniformVolume& referenceImage, const UniformVolume& floatingImage, const Self::Mode mode )
00068 {
00069 switch ( mode )
00070 {
00071 case Self::NONE:
00072 default:
00073 return new AffineXform;
00074 case Self::FOV:
00075 return Self::AlignFieldsOfView( referenceImage, floatingImage );
00076 case Self::COM:
00077 return Self::AlignCentersOfMass( referenceImage, floatingImage );
00078 case Self::PAX:
00079 return Self::AlignPrincipalAxes( referenceImage, floatingImage );
00080 case Self::PHYS:
00081 return Self::AlignDirectionVectors( referenceImage, floatingImage );
00082 }
00083 return new AffineXform;
00084 }
00085
00086 AffineXform*
00087 MakeInitialAffineTransformation
00088 ::AlignDirectionVectors( const UniformVolume& referenceImage, const UniformVolume& floatingImage, const bool centerXform )
00089 {
00090 if ( referenceImage.m_MetaInformation[META_SPACE] != floatingImage.m_MetaInformation[META_SPACE] )
00091 {
00092 StdErr << "ERROR: coordinate spaces '" << referenceImage.m_MetaInformation[META_SPACE]
00093 << "' and '" << floatingImage.m_MetaInformation[META_SPACE] << "' do not match.\n";
00094 return NULL;
00095 }
00096
00097 if ( referenceImage.m_MetaInformation[META_EXTERNAL_SPACE_ID] != floatingImage.m_MetaInformation[META_EXTERNAL_SPACE_ID] )
00098 {
00099 StdErr << "ERROR: semantic coordinate spaces '" << referenceImage.m_MetaInformation[META_EXTERNAL_SPACE_ID]
00100 << "' and '" << floatingImage.m_MetaInformation[META_EXTERNAL_SPACE_ID] << "' do not match.\n";
00101 return NULL;
00102 }
00103
00104 const AffineXform::MatrixType refMatrix = referenceImage.GetImageToPhysicalMatrix();
00105 AffineXform referenceXform( refMatrix );
00106
00107 const AffineXform::MatrixType fltMatrix = floatingImage.GetImageToPhysicalMatrix();
00108 AffineXform floatingXform( fltMatrix );
00109
00110 AffineXform* xform = new AffineXform( referenceXform );
00111 xform->Concat( *floatingXform.GetInverse() );
00112
00113 if ( centerXform )
00114 {
00115 const Vector3D center = referenceImage.GetCenterCropRegion();
00116 xform->ChangeCenter( center );
00117 }
00118
00119 return xform;
00120 }
00121
00122 AffineXform*
00123 MakeInitialAffineTransformation
00124 ::AlignFieldsOfView( const UniformVolume& referenceImage, const UniformVolume& floatingImage )
00125 {
00126 AffineXform* xform = new AffineXform;
00127
00128 const Vector3D translation = floatingImage.GetCenterCropRegion() - referenceImage.GetCenterCropRegion();
00129 xform->SetXlate( translation.begin() );
00130
00131 return xform;
00132 }
00133
00134 AffineXform*
00135 MakeInitialAffineTransformation
00136 ::AlignCentersOfMass( const UniformVolume& referenceImage, const UniformVolume& floatingImage )
00137 {
00138 AffineXform* xform = new AffineXform;
00139
00140 const Vector3D translation = floatingImage.GetCenterOfMass() - referenceImage.GetCenterOfMass();
00141 xform->SetXlate( translation.begin() );
00142
00143 return xform;
00144 }
00145
00146 AffineXform*
00147 MakeInitialAffineTransformation
00148 ::AlignPrincipalAxes( const UniformVolume& referenceImage, const UniformVolume& floatingImage )
00149 {
00150
00151 Matrix3x3<Types::Coordinate> pAxesRef, pAxesFlt;
00152 Vector3D centerOfMassRef, centerOfMassFlt;
00153
00154 referenceImage.GetPrincipalAxes( pAxesRef, centerOfMassRef );
00155 floatingImage.GetPrincipalAxes( pAxesFlt, centerOfMassFlt );
00156
00157 pAxesRef = pAxesRef.GetTranspose();
00158 pAxesFlt = pAxesFlt.GetTranspose();
00159
00160
00161 pAxesRef.Invert3x3();
00162 Matrix3x3<Types::Coordinate> xform3x3 = (pAxesRef * pAxesFlt);
00163
00164 Vector3D xlation = centerOfMassRef;
00165 xform3x3.Multiply( xlation );
00166 xlation = centerOfMassFlt - xlation;
00167
00168
00169 Matrix4x4<Types::Coordinate> xform4x4 = xform3x3;
00170
00171
00172 for ( int i = 0; i < 3; i++ )
00173 {
00174 xform4x4[3][i] = xlation[i];
00175 xform4x4[i][3] = 0;
00176 }
00177 xform4x4[3][3] = 1;
00178
00179 AffineXform* xform = new AffineXform( xform4x4 );
00180 xform->ChangeCenter( centerOfMassRef );
00181
00182 Types::Coordinate* angles = xform->RetAngles();
00183 for ( int i = 0; i < 3; ++i )
00184 {
00185 if ( angles[i] > 90 )
00186 angles[i] -= 180;
00187 else if ( angles[i] < -90 )
00188 angles[i] += 180;
00189 }
00190 xform->SetAngles( angles );
00191
00192 return xform;
00193 }
00194
00195 }