X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=tools%2FclitkAffineTransformGenericFilter.txx;h=93cd16c91c2928455b4af569a450a985ecaa0a49;hb=cb4bdfed13b79735336f2e087a0b9372610aac06;hp=c758cb2f80273b6c7576abfe04626f0adee996ff;hpb=55fe2db2309025f919691272d019f395a3f1dd99;p=clitk.git diff --git a/tools/clitkAffineTransformGenericFilter.txx b/tools/clitkAffineTransformGenericFilter.txx index c758cb2..93cd16c 100644 --- a/tools/clitkAffineTransformGenericFilter.txx +++ b/tools/clitkAffineTransformGenericFilter.txx @@ -135,16 +135,59 @@ AffineTransformGenericFilter::UpdateWithDimAndPixelType() // Matrix typename itk::Matrix matrix; - if (m_ArgsInfo.matrix_given) { - matrix= clitk::ReadMatrix(m_ArgsInfo.matrix_arg); - if (m_Verbose) std::cout<<"Reading the matrix..."< transformParameters(2 * Dimension); + transformParameters.Fill(0.0); + if (m_ArgsInfo.rotate_given) + { + if (Dimension == 2) + transformParameters[0] = m_ArgsInfo.rotate_arg[0]; + else + for (unsigned int i = 0; i < 3; i++) + transformParameters[i] = m_ArgsInfo.rotate_arg[i]; + } + if (m_ArgsInfo.translate_given) + { + int pos = 3; + if (Dimension == 2) + pos = 1; + for (unsigned int i = 0; i < Dimension && i < 3; i++) + transformParameters[pos++] = m_ArgsInfo.translate_arg[i]; + } + if (Dimension == 4) + { + matrix.SetIdentity(); + itk::Matrix tmp = GetForwardAffineMatrix3D(transformParameters); + for (unsigned int i = 0; i < 3; ++i) + for (unsigned int j = 0; j < 3; ++j) + matrix[i][j] = tmp[i][j]; + for (unsigned int i = 0; i < 3; ++i) + matrix[i][4] = tmp[i][3]; + } + else + matrix = GetForwardAffineMatrix(transformParameters); } - if (m_Verbose) std::cout<<"Using the following matrix:"< rotationMatrix=clitk::GetRotationalPartMatrix(matrix); - typename itk::Vector translationPart= clitk::GetTranslationPartMatrix(matrix); + else + { + if (m_ArgsInfo.matrix_given) + { + matrix= clitk::ReadMatrix(m_ArgsInfo.matrix_arg); + if (m_Verbose) std::cout << "Reading the matrix..." << std::endl; + } + else + matrix.SetIdentity(); + } + if (m_Verbose) + std::cout << "Using the following matrix:" << std::endl + << matrix << std::endl; + typename itk::Matrix rotationMatrix = clitk::GetRotationalPartMatrix(matrix); + typename itk::Vector translationPart = clitk::GetTranslationPartMatrix(matrix); // Transform typedef itk::AffineTransform AffineTransformType; @@ -168,7 +211,20 @@ AffineTransformGenericFilter::UpdateWithDimAndPixelType() typename itk::Matrix invRotMatrix( clitk::GetRotationalPartMatrix(invMatrix) ); typename itk::Vector invTrans = clitk::GetTranslationPartMatrix(invMatrix); - // Size is converted to double, transformed and converted back to size type + // Spacing is influenced by affine transform matrix and input direction + typename InputImageType::SpacingType outputSpacing; + outputSpacing = invRotMatrix * + input->GetDirection() * + input->GetSpacing(); + + // Origin is influenced by translation but not by input direction + typename InputImageType::PointType outputOrigin; + outputOrigin = invRotMatrix * + input->GetOrigin() + + invTrans; + + // Size is influenced by affine transform matrix and input direction + // Size is converted to double, transformed and converted back to size type. vnl_vector vnlOutputSize(Dimension); for(unsigned int i=0; i< Dimension; i++) { vnlOutputSize[i] = input->GetLargestPossibleRegion().GetSize()[i]; @@ -178,18 +234,18 @@ AffineTransformGenericFilter::UpdateWithDimAndPixelType() vnlOutputSize; typename OutputImageType::SizeType outputSize; for(unsigned int i=0; i< Dimension; i++) { + // If the size is negative, we have a flip and we must modify + // the origin and the spacing accordingly. + if(vnlOutputSize[i]<0.) { + vnlOutputSize[i] *= -1.; + outputOrigin[i] = outputOrigin[i] + outputSpacing[i] * (vnlOutputSize[i]-1); + outputSpacing[i] *= -1.; + } outputSize[i] = lrint(vnlOutputSize[i]); } resampler->SetSize( outputSize ); - - // Spacing can be dictly computed in the same way - resampler->SetOutputSpacing ( invRotMatrix * - input->GetDirection() * - input->GetSpacing() ); - // Origin is influenced by translation but not by direction - resampler->SetOutputOrigin ( invRotMatrix * - input->GetOrigin() + - invTrans ); + resampler->SetOutputSpacing( outputSpacing ); + resampler->SetOutputOrigin( outputOrigin ); } else { //Size typename OutputImageType::SizeType outputSize; @@ -271,14 +327,59 @@ void AffineTransformGenericFilter::UpdateWithDimAndVectorType() // Matrix typename itk::Matrix matrix; - if (m_ArgsInfo.matrix_given) - matrix= clitk::ReadMatrix(m_ArgsInfo.matrix_arg); + if (m_ArgsInfo.rotate_given || m_ArgsInfo.translate_given) + { + if (m_ArgsInfo.matrix_given) + { + std::cerr << "You must use either rotate/translate or matrix options" << std::cout; + return; + } + itk::Array transformParameters(2 * Dimension); + transformParameters.Fill(0.0); + if (m_ArgsInfo.rotate_given) + { + if (Dimension == 2) + transformParameters[0] = m_ArgsInfo.rotate_arg[0]; + else + for (unsigned int i = 0; i < 3; i++) + transformParameters[i] = m_ArgsInfo.rotate_arg[i]; + } + if (m_ArgsInfo.translate_given) + { + int pos = 3; + if (Dimension == 2) + pos = 1; + for (unsigned int i = 0; i < Dimension && i < 3; i++) + transformParameters[pos++] = m_ArgsInfo.translate_arg[i]; + } + if (Dimension == 4) + { + matrix.SetIdentity(); + itk::Matrix tmp = GetForwardAffineMatrix3D(transformParameters); + for (unsigned int i = 0; i < 3; ++i) + for (unsigned int j = 0; j < 3; ++j) + matrix[i][j] = tmp[i][j]; + for (unsigned int i = 0; i < 3; ++i) + matrix[i][4] = tmp[i][3]; + } + else + matrix = GetForwardAffineMatrix(transformParameters); + } else - matrix.SetIdentity(); - if (m_Verbose) std::cout<<"Using the following matrix:"< rotationMatrix=clitk::GetRotationalPartMatrix(matrix); - typename itk::Vector translationPart= clitk::GetTranslationPartMatrix(matrix); + { + if (m_ArgsInfo.matrix_given) + { + matrix= clitk::ReadMatrix(m_ArgsInfo.matrix_arg); + if (m_Verbose) std::cout << "Reading the matrix..." << std::endl; + } + else + matrix.SetIdentity(); + } + if (m_Verbose) + std::cout << "Using the following matrix:" << std::endl + << matrix << std::endl; + typename itk::Matrix rotationMatrix = clitk::GetRotationalPartMatrix(matrix); + typename itk::Vector translationPart = clitk::GetTranslationPartMatrix(matrix); // Transform typedef itk::AffineTransform AffineTransformType;