X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=segmentation%2FclitkMotionMaskGenericFilter.txx;h=fd21b4629d4da99590b741e4fe7fa9ff634cfb50;hb=05e26237e30a14a226cb4eb480a0eb9697f8ba06;hp=d2de0d4dd8543d13312da958d6912443d1f4162c;hpb=a55c4b8805a34466d29bdcdb24b4f107b2515e23;p=clitk.git diff --git a/segmentation/clitkMotionMaskGenericFilter.txx b/segmentation/clitkMotionMaskGenericFilter.txx old mode 100755 new mode 100644 index d2de0d4..fd21b46 --- a/segmentation/clitkMotionMaskGenericFilter.txx +++ b/segmentation/clitkMotionMaskGenericFilter.txx @@ -3,7 +3,7 @@ Authors belong to: - University of LYON http://www.universite-lyon.fr/ - - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr + - Léon Bérard cancer center http://www.centreleonberard.fr - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr This software is distributed WITHOUT ANY WARRANTY; without even @@ -14,7 +14,7 @@ - BSD See included LICENSE.txt file - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html -======================================================================-====*/ +===========================================================================**/ #ifndef clitkMotionMaskGenericFilter_txx #define clitkMotionMaskGenericFilter_txx @@ -27,6 +27,8 @@ * ===================================================*/ +#include "itkLabelImageToShapeLabelMapFilter.h" +#include "itkShapeLabelObject.h" namespace clitk { @@ -107,10 +109,13 @@ MotionMaskGenericFilter::GetAirImage(typename itk::Image:: typename InternalImageType::IndexType index; while(!it.IsAtEnd()) { index=it.GetIndex(); + + //Pad borders of all dimensions but 2 (cranio-caudal) for (unsigned int i=0; iGetLargestPossibleRegion().GetIndex()[i] - || index[i]==(unsigned int)air->GetLargestPossibleRegion().GetIndex()[i]+ (unsigned int) air->GetLargestPossibleRegion().GetSize()[i]-1)) + if(i==2) + continue; + if(index[i]==air->GetLargestPossibleRegion().GetIndex()[i] + || index[i]==(unsigned int)air->GetLargestPossibleRegion().GetIndex()[i]+ (unsigned int) air->GetLargestPossibleRegion().GetSize()[i]-1) it.Set(1); } ++it; @@ -139,10 +144,13 @@ MotionMaskGenericFilter::GetAirImage(typename itk::Image:: typename InternalImageType::IndexType index; while(!it.IsAtEnd()) { index=it.GetIndex(); + + //Pad borders of all dimensions but 2 (cranio-caudal) for (unsigned int i=0; iGetLargestPossibleRegion().GetIndex()[i] - || index[i]==(unsigned int)air->GetLargestPossibleRegion().GetIndex()[i]+ (unsigned int) air->GetLargestPossibleRegion().GetSize()[i]-1)) + if(i==2) + continue; + if(index[i]==air->GetLargestPossibleRegion().GetIndex()[i] + || index[i]==(unsigned int)air->GetLargestPossibleRegion().GetIndex()[i]+ (unsigned int) air->GetLargestPossibleRegion().GetSize()[i]-1) it.Set(binarizeFilter->GetInsideValue()); } ++it; @@ -371,6 +379,8 @@ MotionMaskGenericFilter::GetLungsImage(typename itk::Image connectFilter->SetBackgroundValue(0); connectFilter->SetFullyConnected(true); if (m_Verbose) std::cout<<"Labeling the connected components..."<Update(); + if (m_Verbose) std::cout<<"found "<< connectFilter->GetObjectCount() << std::endl; //--------------------------------- // Sort the labels according to size @@ -378,7 +388,7 @@ MotionMaskGenericFilter::GetLungsImage(typename itk::Image typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New(); relabelFilter->SetInput(connectFilter->GetOutput()); if (m_Verbose) std::cout<<"Sorting the labels..."< (relabelFilter->GetOutput(), "/home/jef/tmp/labels.mhd"); + // writeImage (relabelFilter->GetOutput(), "/home/vdelmon/tmp/labels.mhd"); //--------------------------------- // Keep the label @@ -472,7 +482,7 @@ MotionMaskGenericFilter::Resample( typename itk::Image typename itk::Image::Pointer -MotionMaskGenericFilter::InitializeEllips( typename itk::Vector center, typename itk::Image::Pointer bones_low ) +MotionMaskGenericFilter::InitializeEllips( typename itk::Vector center, typename itk::Image::Pointer bones_low, typename itk::Image::Pointer lungs_low ) { // ImageTypes @@ -503,24 +513,85 @@ MotionMaskGenericFilter::InitializeEllips( typename itk::Vector offset; - if(m_ArgsInfo.offset_given== Dimension) { - for(unsigned int i=0; i centerEllips; + typename itk::Vector axes; + if (m_ArgsInfo.ellipseAutoDetect_flag) { + if(m_Verbose) { + std::cout<<"Auto-detecting intial ellipse..."<GetLargestPossibleRegion(); + typename InternalImageType::SizeType size = region_before.GetSize(); + size[2] /= 2; + region.SetSize(size); + lungs_low->SetRegions(region); + + // compute statistics of the (mirroed) lung region in order to guess the params of the ellipse + typedef itk::LabelImageToShapeLabelMapFilter LabelImageToShapeLabelMapFilter; + typename LabelImageToShapeLabelMapFilter::Pointer label_filter = LabelImageToShapeLabelMapFilter::New(); + label_filter->SetInput(lungs_low); + label_filter->Update(); + + typename InternalImageType::SpacingType spacing = lungs_low->GetSpacing(); + typedef typename LabelImageToShapeLabelMapFilter::OutputImageType::LabelObjectType LabelType; + const LabelType* label = dynamic_cast(label_filter->GetOutput()->GetNthLabelObject(0)); + + // lungs' barycenter + typename LabelType::CentroidType lung_centroid = label->GetCentroid(); + + // try to guess ideal ellipse axes from the lungs' bounding box and centroid + // with some hard-coded "magic" constants... + typename LabelType::RegionType lung_bbox = label->GetBoundingBox(); + + axes[0] = 0.95*lung_bbox.GetSize()[0]*spacing[0]/2; + axes[1] = 0.3*lung_bbox.GetSize()[1]*spacing[1]/2; + axes[2] = 1.25*fabs(lung_centroid[2] - center[2]); + + // ellipse's center in XY is the center of the lungs' bounding box + typename InternalImageType::PointType origin = lungs_low->GetOrigin(); + centerEllips[0] = origin[0] + (lung_bbox.GetIndex()[0] + lung_bbox.GetSize()[0]/2)*spacing[0]; + centerEllips[1] = origin[1] + (lung_bbox.GetIndex()[1] + lung_bbox.GetSize()[1]/2)*spacing[1]; + centerEllips[2] = center[2]; + + lungs_low->SetRegions(region_before); + + if(m_Verbose) { + std::cout << "Lungs'centroid at " << lung_centroid << std::endl; + std::cout << "Ellipse center at " << centerEllips << std::endl; + std::cout << "Ellipse axes as " << axes << std::endl; + std::cout << "Lung's bounding box (index,size) " << lung_bbox.GetIndex() << lung_bbox.GetSize() << std::endl; + } } - itk::Vector centerEllips=center+offset; - if (m_Verbose) { - std::cout<<"Placing the center of the initial ellipsoide at (mm) "< offset; + if(m_ArgsInfo.offset_given== Dimension) { + for(unsigned int i=0; iAllocate(); ellips->FillBuffer(0); - // Axes - typename itk::Vector axes; - if (m_ArgsInfo.axes_given==Dimension) - for(unsigned int i=0; iGetLargestPossibleRegion()); itEllips.GoToBegin(); @@ -719,7 +779,7 @@ MotionMaskGenericFilter::UpdateWithDimAndPixelType() //---------------------------------------------------------------------------------------------------- // Ellipsoide initialization //---------------------------------------------------------------------------------------------------- - typename InternalImageType::Pointer m_Ellips= InitializeEllips(center,bones_low); + typename InternalImageType::Pointer m_Ellips= InitializeEllips(center,bones_low,lungs_low); //---------------------------------------------------------------------------------------------------- // Grow ellips @@ -938,6 +998,10 @@ MotionMaskGenericFilter::UpdateWithDimAndPixelType() distanceMapImageFilter->SetInsideIsPositive(false); if (m_Verbose) std::cout<<"Calculating the distance map..."<Update(); + if (m_ArgsInfo.writeDistMap_given) { + writeImage(distanceMapImageFilter->GetOutput(), m_ArgsInfo.writeDistMap_arg, m_Verbose); + + } //--------------------------------- // Grow while monitoring detection point @@ -1063,6 +1127,10 @@ MotionMaskGenericFilter::UpdateWithDimAndPixelType() distanceMapImageFilter->SetInsideIsPositive(false); if (m_Verbose) std::cout<<"Calculating distance map..."<Update(); + if (m_ArgsInfo.writeDistMap_given) { + writeImage(distanceMapImageFilter->GetOutput(), m_ArgsInfo.writeDistMap_arg, m_Verbose); + + } //--------------------------------- // Grow while monitoring lung volume coverage