From: David Sarrut Date: Fri, 5 Sep 2014 14:12:14 +0000 (+0200) Subject: Merge branch 'master' of git.creatis.insa-lyon.fr:clitk X-Git-Tag: v1.4.0~16^2~10^2 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=e06bbd15e271bf0a4092b673399d040a5cb25efe;hp=1eb88e752e0985548fc83742ed92ab395f9c77fc;p=clitk.git Merge branch 'master' of git.creatis.insa-lyon.fr:clitk --- diff --git a/common/clitkCommon.h b/common/clitkCommon.h index 2f5b26f..b58974a 100644 --- a/common/clitkCommon.h +++ b/common/clitkCommon.h @@ -1,7 +1,7 @@ /*========================================================================= Program: vv http://www.creatis.insa-lyon.fr/rio/vv - Authors belong to: + Authors belong to: - University of LYON http://www.universite-lyon.fr/ - Léon Bérard cancer center http://www.centreleonberard.fr - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr @@ -34,7 +34,7 @@ #include // Include for "rusage" -#include +#include #if defined(unix) || defined(__APPLE__) # include # include @@ -51,7 +51,7 @@ namespace clitk { typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; - + #define CLITK_TRY_CATCH_EXIT(func) \ try { \ func; \ @@ -68,13 +68,13 @@ namespace clitk { std::cout << "Unknown excpetion" << std::endl; \ exit(-3); \ } - + //-------------------------------------------------------------------- // when everything goes wrong #define WHEREAMI "[ " << __FILE__ << " ] line " << __LINE__ -#define FATAL(a) std::cerr << "ERROR in " << WHEREAMI << ": " << a; exit(0); - +#define FATAL(a) { std::cerr << "ERROR in " << WHEREAMI << ": " << a; exit(0); } + //-------------------------------------------------------------------- // GGO with modified struct name #define GGO(ggo_filename, args_info) \ @@ -82,7 +82,7 @@ namespace clitk { cmdline_parser_##ggo_filename##2(argc, argv, &args_info, 1, 1, 0); \ if (args_info.config_given) \ cmdline_parser_##ggo_filename##_configfile (args_info.config_arg, &args_info, 0, 0, 1); \ - else cmdline_parser_##ggo_filename(argc, argv, &args_info); + else cmdline_parser_##ggo_filename(argc, argv, &args_info); //-------------------------------------------------------------------- // skip line with # @@ -95,15 +95,15 @@ namespace clitk { //-------------------------------------------------------------------- // Return filename extension std::string GetExtension(const std::string& filename); - + //-------------------------------------------------------------------- // Convert float, double ... to string template std::string toString(const T & t); template std::string toStringVector(const T * t, const int n); template std::string toStringVector(const T & t, const int n); template std::string toStringVector(const std::vector & t); - template bool fromString(T& t, - const std::string& s, + template bool fromString(T& t, + const std::string& s, std::ios_base& (*f)(std::ios_base&)=std::dec); //-------------------------------------------------------------------- @@ -129,7 +129,7 @@ namespace clitk { // Return the name of a type as a string template std::string GetTypeAsString(); - + //-------------------------------------------------------------------- // Convert radian / degree double rad2deg(double anglerad); @@ -152,13 +152,13 @@ namespace clitk { std::string CreateListOfTypes(bool last=true) { return GetTypeAsString(); } - + template std::string CreateListOfTypes(bool last=true) { if (last) return CreateListOfTypes()+" and "+CreateListOfTypes(); else return CreateListOfTypes()+", "+CreateListOfTypes(); } - + template std::string CreateListOfTypes(bool last=true) { if (last) return CreateListOfTypes(false)+" and "+CreateListOfTypes(); @@ -195,7 +195,7 @@ namespace clitk { else return CreateListOfTypes(false)+", "+CreateListOfTypes(); } //-------------------------------------------------------------------- - + //-------------------------------------------------------------------- void FindAndReplace(std::string & line, const std::string & tofind, const std::string & replacement); void FindAndReplace(std::string & line, const std::vector & tofind, const std::vector & toreplace); @@ -203,8 +203,8 @@ namespace clitk { //-------------------------------------------------------------------- //-------------------------------------------------------------------- - double ComputeEuclideanDistanceFromPointToPlane(const itk::ContinuousIndex point, - const itk::ContinuousIndex pointInPlane, + double ComputeEuclideanDistanceFromPointToPlane(const itk::ContinuousIndex point, + const itk::ContinuousIndex pointInPlane, const itk::ContinuousIndex normalPlane); //-------------------------------------------------------------------- @@ -232,9 +232,9 @@ namespace clitk { //-------------------------------------------------------------------- // Convert a map to a vector - template + template void MapToVecFirst(const M & m, V & v); - template + template void MapToVecSecond(const M & m, V & v); //-------------------------------------------------------------------- @@ -247,4 +247,3 @@ namespace clitk { } // end namespace #endif /* end #define CLITKCOMMON_H */ - diff --git a/common/clitkDD.h b/common/clitkDD.h index 97ba443..c5a9996 100644 --- a/common/clitkDD.h +++ b/common/clitkDD.h @@ -38,6 +38,6 @@ template void _print_container(T const& a) { for(typename T::const_iterator i=a.begin();i!=a.end();++i) { std::cout << *i << " "; };} -#define DDS(a) { std::cout << #a " = [ "; _print_container(a) ; std::cout << " ]" << std::endl;std::cout.flush():} +#define DDS(a) { std::cout << #a " = [ "; _print_container(a) ; std::cout << " ]" << std::endl;std::cout.flush();} #endif diff --git a/common/clitkTimer.cxx b/common/clitkTimer.cxx index cd74428..329ca13 100644 --- a/common/clitkTimer.cxx +++ b/common/clitkTimer.cxx @@ -64,13 +64,15 @@ void clitk::Timer::Stop(bool accumulate) mElapsed += (mEnd.ru_utime.tv_usec - mBegin.ru_utime.tv_usec)+ (mEnd.ru_utime.tv_sec - mBegin.ru_utime.tv_sec)*1000000; } + else #elif defined(_WIN32) QueryPerformanceCounter((LARGE_INTEGER*)&mEnd); if (accumulate) { mElapsed += ((mEnd-mBegin)*1000000)/(long double)mFrequency; } + else #endif - else { + { mNumberOfCall--; } } @@ -114,4 +116,3 @@ void clitk::Timer::Reset() // #endif // If UNIX #endif /* end #define CLITKTIMER_CXX */ - diff --git a/itk/clitkInvertVFFilter.txx b/itk/clitkInvertVFFilter.txx index 34500a3..e26fed7 100644 --- a/itk/clitkInvertVFFilter.txx +++ b/itk/clitkInvertVFFilter.txx @@ -145,7 +145,7 @@ void HelperClass1::ThreadedGenerateData(const O typedef typename OutputImageType::PixelType DisplacementType; DisplacementType displacement; inputIt.GoToBegin(); - + typename OutputImageType::SizeType size = outputPtr->GetLargestPossibleRegion().GetSize(); //define some temp variables @@ -199,7 +199,7 @@ void HelperClass1::ThreadedGenerateData(const O overlap *= 1.0 - distance[dim]; } upper >>= 1; - + if (neighIndex[dim] >= size[dim]) neighIndex[dim] = size[dim] - 1; } @@ -320,7 +320,10 @@ protected: //Empty constructor template HelperClass2::HelperClass2() { - m_EdgePaddingValue=itk::NumericTraits::Zero; + PixelType zero; + for(unsigned int i=0;i ::Zero; } @@ -333,7 +336,7 @@ template void HelperClass2GetInput(); @@ -383,9 +386,9 @@ template void HelperClass2 InvertVFFilter::InvertVFFilter() { - m_EdgePaddingValue=itk::NumericTraits::Zero; //no other reasonable value? + + //m_EdgePaddingValue=itk::NumericTraits::Zero; //no other reasonable value? + PixelType zero; + for(unsigned int i=0;i void InvertVFFilterSetNthOutput(0, helper2->GetOutput()); - + //std::cout << "InvertVFFilter::GenerateData - OUT" << std::endl; } diff --git a/tools/clitkImageConvert.cxx b/tools/clitkImageConvert.cxx index 3a9beaf..8138682 100644 --- a/tools/clitkImageConvert.cxx +++ b/tools/clitkImageConvert.cxx @@ -68,6 +68,7 @@ int main(int argc, char * argv[]) filter->SetIOVerbose(args_info.verbose_flag); filter->SetOutputFilename(output); filter->SetVV(args_info.vv_flag); + filter->SetCorrectNegativeSpacingFlag(args_info.correct_flag); filter->EnableWriteCompression(args_info.compression_flag); if (args_info.type_given) filter->SetOutputPixelType(args_info.type_arg); @@ -80,4 +81,3 @@ int main(int argc, char * argv[]) //-------------------------------------------------------------------= #endif /* end #define CLITKIMAGECONVERT_CXX */ - diff --git a/tools/clitkImageConvert.ggo b/tools/clitkImageConvert.ggo index b6f003c..6d74318 100644 --- a/tools/clitkImageConvert.ggo +++ b/tools/clitkImageConvert.ggo @@ -10,3 +10,4 @@ option "type" t "Output type (float, ushort ...)" option "verbose" v "Verbose" flag off option "compression" c "Compress output" flag off option "vv" - "Read image as in vv and save transform in meta information" flag off +option "correct" - "Correct dicom with negative Z spacing" flag off diff --git a/tools/clitkImageConvertGenericFilter.cxx b/tools/clitkImageConvertGenericFilter.cxx index 2783053..a603385 100644 --- a/tools/clitkImageConvertGenericFilter.cxx +++ b/tools/clitkImageConvertGenericFilter.cxx @@ -15,12 +15,21 @@ - BSD See included LICENSE.txt file - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html ===========================================================================**/ + #ifndef CLITKIMAGECONVERTGENERICFILTER_CXX #define CLITKIMAGECONVERTGENERICFILTER_CXX #include "clitkImageConvertGenericFilter.h" #include "vvImageReader.h" #include "vvImageWriter.h" +#include "itkFlipImageFilter.h" +#include "itkGDCMImageIO.h" + +#include "gdcmReader.h" +#include "gdcmAttribute.h" +#include "gdcmPrinter.h" +#include "gdcmDict.h" +#include "gdcmStringFilter.h" //-------------------------------------------------------------------- clitk::ImageConvertGenericFilter::ImageConvertGenericFilter(): @@ -30,7 +39,8 @@ clitk::ImageConvertGenericFilter::ImageConvertGenericFilter(): mDisplayWarning = true; mWarning = ""; mWarningOccur = false; - + SetCorrectNegativeSpacingFlag(false); + InitializeImageType<2>(); InitializeImageType<3>(); InitializeImageType<4>(); @@ -90,12 +100,85 @@ void clitk::ImageConvertGenericFilter::UpdateWithInputImageType() return; } else if ((m_PixelTypeName == mOutputPixelTypeName) || (mOutputPixelTypeName == "NotSpecified")) { + + // Get input image typename InputImageType::Pointer input = this->template GetInput(0); - this->SetNextOutput(input); + + if (mCorrectNegativeSpacingFlag) { + // Read dicom + gdcm::Reader reader; + reader.SetFileName(m_InputFilenames[0].c_str()); + // if (!reader.CanReadFile(m_InputFilenames[0])) { + // std::cout << "Error: " << m_InputFilenames[0] << " is not a dicom file. Abort." << std::endl; + // exit(0); + // } + reader.Read(); + + // the dataset is the the set of element we are interested in: + gdcm::DataSet & ds = reader.GetFile().GetDataSet(); + + // Read the attribute SpacingBetweenSlices, check if negative and replace + gdcm::Attribute<0x0018,0x0088> SpacingBetweenSlices; + SpacingBetweenSlices.SetFromDataSet(ds); + double s = SpacingBetweenSlices.GetValue(); + if (s >=0) { + std::cout << "Error: no negative spacing found SpacingBetweenSlices = " << s << " Abort. " << std::endl; + exit(0); + } + s = -s; + + // Set spacing + typename InputImageType::SpacingType spacing = input->GetSpacing(); + spacing[2] = s; + input->SetSpacing(spacing); + + // Flip + typedef itk::FlipImageFilter< InputImageType > FilterType; + typename FilterType::Pointer filter = FilterType::New(); + typedef typename FilterType::FlipAxesArrayType FlipAxesArrayType; + FlipAxesArrayType flipArray; + flipArray[0] = false; + flipArray[1] = false; + flipArray[2] = true; + filter->SetFlipAxes(flipArray); + filter->SetInput(input); + filter->Update(); + + // Read the attribute Image Position (Patient) + gdcm::Tag DetectorInformationSequenceTag(0x0054,0x0022); + const gdcm::DataElement & DIS = ds.GetDataElement(DetectorInformationSequenceTag); + gdcm::SmartPointer sqf = DIS.GetValueAsSQ(); + gdcm::Item & item = sqf->GetItem(1); + gdcm::DataSet & ds_position = item.GetNestedDataSet(); + gdcm::Attribute<0x0020,0x0032> ImagePositionPatient; + ImagePositionPatient.SetFromDataSet(ds_position); + double x = ImagePositionPatient.GetValue(0); + double y = ImagePositionPatient.GetValue(1); + double z = ImagePositionPatient.GetValue(2); + + // Set offset + typename InputImageType::PointType origin = input->GetOrigin(); + origin[0] = x; + origin[1] = y; + origin[2] = z; + input->SetOrigin(origin); + + // Orientation + typename InputImageType::DirectionType direction = input->GetDirection(); + direction[2][2] = -1; + input->SetDirection(direction); + + // Empty meta info + itk::MetaDataDictionary dict;// = new itk::MetaDataDictionary; + input->SetMetaDataDictionary(dict); + + this->SetNextOutput(input); + } + } else { - // "trick" to call independent versions of update according to the + // "trick" to call independent versions of update according to the // pixel type (vector or scalar), using partial specializations - if (!UpdateWithSelectiveOutputType::IS_VECTOR>::Run(*this, mOutputPixelTypeName)) + if (!UpdateWithSelectiveOutputType::IS_VECTOR>::Run(*this, mOutputPixelTypeName)) exit(-1); } } @@ -143,4 +226,3 @@ void clitk::ImageConvertGenericFilter::CheckTypes( #endif /* end #define CLITKIMAGECONVERTGENERICFILTER_CXX */ - diff --git a/tools/clitkImageConvertGenericFilter.h b/tools/clitkImageConvertGenericFilter.h index 8ffb360..aa8b2ba 100644 --- a/tools/clitkImageConvertGenericFilter.h +++ b/tools/clitkImageConvertGenericFilter.h @@ -1,7 +1,7 @@ /*========================================================================= Program: vv http://www.creatis.insa-lyon.fr/rio/vv - Authors belong to: + Authors belong to: - University of LYON http://www.universite-lyon.fr/ - Léon Bérard cancer center http://www.centreleonberard.fr - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr @@ -23,7 +23,7 @@ * @author David Sarrut * @date 05 May 2008 10:40:24 - * @brief + * @brief ===================================================================*/ @@ -36,7 +36,7 @@ namespace clitk { - + template class ImageConvertTraits { @@ -47,17 +47,17 @@ namespace clitk { } }; - template < class TPixel, unsigned int Comp > - class ImageConvertTraits< itk::Vector > - { - public: - enum { IS_VECTOR = true }; + template < class TPixel, unsigned int Comp > + class ImageConvertTraits< itk::Vector > + { + public: + enum { IS_VECTOR = true }; }; - class ImageConvertGenericFilter: + class ImageConvertGenericFilter: public clitk::ImageToImageGenericFilter { - - public: + + public: // constructor - destructor ImageConvertGenericFilter(); @@ -68,7 +68,7 @@ namespace clitk { // New itkNewMacro(Self); - + // Members functions std::string GetInputPixelTypeName() { return m_PixelTypeName; } std::string GetOutputPixelTypeName() { return mOutputPixelTypeName; } @@ -77,15 +77,16 @@ namespace clitk { bool IsWarningOccur() { return mWarningOccur; } std::string & GetWarning() { return mWarning; } void EnableDisplayWarning(bool b) { mDisplayWarning = b; } + void SetCorrectNegativeSpacingFlag(bool b) { mCorrectNegativeSpacingFlag = b; } //-------------------------------------------------------------------- // Main function called each time the filter is updated - template + template void UpdateWithInputImageType(); template void CheckTypes(std::string inType, std::string outType); - + protected: template void InitializeImageType(); @@ -94,6 +95,7 @@ namespace clitk { bool mWarningOccur; bool mDisplayWarning; bool mVV; + bool mCorrectNegativeSpacingFlag; private: template @@ -119,17 +121,17 @@ namespace clitk { else { std::string list = CreateListOfTypes(); - std::cerr << "Error, I don't know the vector output type '" << outputPixelType + std::cerr << "Error, I don't know the vector output type '" << outputPixelType << "'. " << std::endl << "Known types are " << list << "." << std::endl; return false; } - + return true; } private: - - template + + template static void UpdateWithOutputType(ImageConvertGenericFilter& filter) { // Read @@ -152,7 +154,7 @@ namespace clitk { filter.SetNextOutput(cast_filter->GetOutput()); } }; - + template class UpdateWithSelectiveOutputType { @@ -160,7 +162,7 @@ namespace clitk { static bool Run(ImageConvertGenericFilter& filter, std::string outputPixelType) { /* - // RP: future conversions? + // RP: future conversions? if (IsSameType(outputPixelType)) UpdateWithOutputVectorType(); else if (IsSameType(outputPixelType)) @@ -171,7 +173,7 @@ namespace clitk { UpdateWithOutputVectorType(); else if (IsSameType(outputPixelType)) UpdateWithOutputVectorType(); - else + else */ if (IsSameType(outputPixelType)) UpdateWithOutputVectorType(filter); @@ -180,17 +182,17 @@ namespace clitk { else { std::string list = CreateListOfTypes(); - std::cerr << "Error, I don't know the vector output type '" << outputPixelType + std::cerr << "Error, I don't know the vector output type '" << outputPixelType << "'. " << std::endl << "Known types are " << list << "." << std::endl; return false; } - + return true; } - + private: - - template + + template static void UpdateWithOutputVectorType(ImageConvertGenericFilter& filter) { // Read @@ -201,7 +203,7 @@ namespace clitk { // Warning filter.CheckTypes(filter.GetInputPixelTypeName(), filter.GetOutputPixelTypeName()); - + // Cast typedef itk::Image, InputImageType::ImageDimension> OutputImageType; typedef itk::VectorCastImageFilter FilterType; @@ -220,4 +222,3 @@ namespace clitk { } // end namespace #endif /* end #define CLITKIMAGECONVERTGENERICFILTER_H */ - diff --git a/tools/clitkImageStatisticsGenericFilter.txx b/tools/clitkImageStatisticsGenericFilter.txx index 5d46240..32b31bc 100644 --- a/tools/clitkImageStatisticsGenericFilter.txx +++ b/tools/clitkImageStatisticsGenericFilter.txx @@ -156,7 +156,7 @@ namespace clitk } else { - std::cerr << "Mask image has a different size/spacing than input. Abort" << std::endl; + std::cerr << "Mask image has a different size/spacing than input. Abort. (Use option to resize)" << std::endl; exit(-1); } } @@ -169,6 +169,7 @@ namespace clitk labelImage->SetRegions(input->GetLargestPossibleRegion()); labelImage->SetOrigin(input->GetOrigin()); labelImage->SetSpacing(input->GetSpacing()); + labelImage->SetDirection(input->GetDirection()); labelImage->Allocate(); labelImage->FillBuffer(m_ArgsInfo.label_arg[0]); } @@ -212,7 +213,7 @@ namespace clitk std::cout<,3>::Pointer AverageField(itk::Image::Zero; + VFPixelType zeroVector;//=itk::NumericTraits::Zero; + for(unsigned int i=0;i