Shrink the image borders to a minimum considering a background color. More...
#include <mitkAutoCropImageFilter.h>
Public Types | |
typedef itk::ImageRegion< 3 > | RegionType |
typedef AutoCropImageFilter | Self |
typedef SubImageSelector | Superclass |
typedef itk::SmartPointer< Self > | Pointer |
typedef itk::SmartPointer < const Self > | ConstPointer |
Public Member Functions | |
virtual const char * | GetClassName () const |
virtual float | GetBackgroundValue () const |
virtual void | SetBackgroundValue (float _arg) |
virtual float | GetMarginFactor () const |
virtual void | SetMarginFactor (float _arg) |
void | SetCroppingRegion (RegionType overrideRegion) |
virtual const std::type_info & | GetOutputPixelType () |
Static Public Member Functions | |
static Pointer | New () |
Protected Types | |
typedef itk::Image< float, 3 > | ImageType |
typedef ImageType::Pointer | ImagePointer |
typedef itk::CropImageFilter < ImageType, ImageType > | CropFilterType |
Protected Member Functions | |
AutoCropImageFilter () | |
virtual | ~AutoCropImageFilter () |
void | ComputeNewImageBounds () |
template<typename TPixel , unsigned int VImageDimension> | |
void | ITKCrop3DImage (itk::Image< TPixel, VImageDimension > *inputItkImage, unsigned int timestep) |
virtual void | GenerateOutputInformation () |
virtual void | GenerateInputRequestedRegion () |
virtual void | GenerateData () |
A version of GenerateData() specific for image processing filters. | |
Protected Attributes | |
float | m_BackgroundValue |
RegionType | m_CroppingRegion |
float | m_MarginFactor |
ImageType::RegionType::SizeType | m_RegionSize |
ImageType::RegionType::IndexType | m_RegionIndex |
CropFilterType::SizeType | m_LowerBounds |
CropFilterType::SizeType | m_UpperBounds |
mitk::ImageTimeSelector::Pointer | m_TimeSelector |
mitk::SlicedData::RegionType | m_InputRequestedRegion |
itk::TimeStamp | m_TimeOfHeaderInitialization |
bool | m_OverrideCroppingRegion |
Shrink the image borders to a minimum considering a background color.
This filter determines the smallest bounding box of all pixels different from the background, and returns an output image which has been cropped to this size. The box calculated this way is not the smallest possible box, but the box with the smallest sides perpendicular to the world coordinate system.
The filter works on 3D and 4D image data. For the 4D case, the smallest box is calculated with side lengths as the maximum of single side lengths from all time steps.
2D images are not supported, and will never be.
It is also possible to set the region to be cropped manually using the SetCroppingRegion() method.
A margin can be set to enlarge the cropped region with a constant factor in all directions around the smallest possible.
Definition at line 59 of file mitkAutoCropImageFilter.h.
typedef itk::SmartPointer<const Self> mitk::AutoCropImageFilter::ConstPointer |
Definition at line 65 of file mitkAutoCropImageFilter.h.
typedef itk::CropImageFilter<ImageType,ImageType> mitk::AutoCropImageFilter::CropFilterType [protected] |
Definition at line 112 of file mitkAutoCropImageFilter.h.
typedef ImageType::Pointer mitk::AutoCropImageFilter::ImagePointer [protected] |
Definition at line 111 of file mitkAutoCropImageFilter.h.
typedef itk::Image<float,3> mitk::AutoCropImageFilter::ImageType [protected] |
Definition at line 110 of file mitkAutoCropImageFilter.h.
typedef itk::SmartPointer<Self> mitk::AutoCropImageFilter::Pointer |
Definition at line 65 of file mitkAutoCropImageFilter.h.
typedef itk::ImageRegion<3> mitk::AutoCropImageFilter::RegionType |
Definition at line 63 of file mitkAutoCropImageFilter.h.
Definition at line 65 of file mitkAutoCropImageFilter.h.
Definition at line 65 of file mitkAutoCropImageFilter.h.
mitk::AutoCropImageFilter::AutoCropImageFilter | ( | ) | [protected] |
Definition at line 27 of file mitkAutoCropImageFilter.cpp.
: m_BackgroundValue(0), m_MarginFactor(1.0), m_TimeSelector(NULL), m_OverrideCroppingRegion(false) { }
mitk::AutoCropImageFilter::~AutoCropImageFilter | ( | ) | [protected, virtual] |
Definition at line 37 of file mitkAutoCropImageFilter.cpp.
{ }
void mitk::AutoCropImageFilter::ComputeNewImageBounds | ( | ) | [protected] |
Definition at line 200 of file mitkAutoCropImageFilter.cpp.
References mitk::CastToItkImage(), mitk::Image::GetDimension(), and mitk::ImageTimeSelector::New().
{ mitk::Image::Pointer inputMitk = const_cast< mitk::Image * > ( this->GetInput() ); if (m_OverrideCroppingRegion) { for (unsigned int i=0; i<3; ++i) { m_RegionIndex[i] = m_CroppingRegion.GetIndex()[i]; m_RegionSize[i] = m_CroppingRegion.GetSize()[i]; if (m_RegionIndex[i] >= inputMitk->GetDimension(i)) { itkExceptionMacro("Cropping index is not inside the image. " << std::endl << "Index:" << std::endl << m_CroppingRegion.GetIndex() << std::endl << "Size:" << std::endl << m_CroppingRegion.GetSize()); } if (m_RegionIndex[i] + m_RegionSize[i] >= inputMitk->GetDimension(i)) { m_RegionSize[i] = inputMitk->GetDimension(i) - m_RegionIndex[i]; } } for (unsigned int i=0; i<3; ++i) { m_RegionIndex[i] = m_CroppingRegion.GetIndex()[i]; m_RegionSize[i] = m_CroppingRegion.GetSize()[i]; m_LowerBounds[i] = m_CroppingRegion.GetIndex()[i]; m_UpperBounds[i] = inputMitk->GetDimension(i)-m_CroppingRegion.GetSize()[i]-m_LowerBounds[i]; } } else { // Check if a 3D or 4D image is present unsigned int timeSteps = 1; if (inputMitk->GetDimension() == 4 ) timeSteps = inputMitk->GetDimension(3); ImageType::IndexType minima,maxima; if (inputMitk->GetDimension() == 4) { // initialize with time step 0 m_TimeSelector = mitk::ImageTimeSelector::New(); m_TimeSelector->SetInput( inputMitk ); m_TimeSelector->SetTimeNr( 0 ); m_TimeSelector->UpdateLargestPossibleRegion(); inputMitk = m_TimeSelector->GetOutput(); } ImagePointer inputItk = ImageType::New(); mitk::CastToItkImage( inputMitk , inputItk ); // it is assumed that all volumes in a time series have the same 3D dimensions ImageType::RegionType origRegion = inputItk->GetLargestPossibleRegion(); // Initialize min and max on the first (or only) time step maxima = inputItk->GetLargestPossibleRegion().GetIndex(); minima[0] = inputItk->GetLargestPossibleRegion().GetSize()[0]; minima[1] = inputItk->GetLargestPossibleRegion().GetSize()[1]; minima[2] = inputItk->GetLargestPossibleRegion().GetSize()[2]; typedef itk::ImageRegionConstIterator< ImageType > ConstIteratorType; for(unsigned int idx = 0; idx < timeSteps; ++idx) { // if 4D image, update time step and itk image if( idx > 0) { m_TimeSelector->SetTimeNr( idx ); m_TimeSelector->UpdateLargestPossibleRegion(); inputMitk = m_TimeSelector->GetOutput(); mitk::CastToItkImage( inputMitk , inputItk ); } ConstIteratorType inIt( inputItk, origRegion ); for ( inIt.GoToBegin(); !inIt.IsAtEnd(); ++inIt) { float pix_val = inIt.Get(); if ( fabs(pix_val - m_BackgroundValue) > mitk::eps ) { for (int i=0; i < 3; i++) { minima[i] = vnl_math_min((int)minima[i],(int)(inIt.GetIndex()[i])); maxima[i] = vnl_math_max((int)maxima[i],(int)(inIt.GetIndex()[i])); } } } } typedef ImageType::RegionType::SizeType::SizeValueType SizeValueType; m_RegionSize[0] = (SizeValueType)(m_MarginFactor * (maxima[0] - minima[0] + 1 )); m_RegionSize[1] = (SizeValueType)(m_MarginFactor * (maxima[1] - minima[1] + 1 )); m_RegionSize[2] = (SizeValueType)(m_MarginFactor * (maxima[2] - minima[2] + 1 )); m_RegionIndex = minima; m_RegionIndex[0] -= (m_RegionSize[0] - maxima[0] + minima[0] - 1 )/2; m_RegionIndex[1] -= (m_RegionSize[1] - maxima[1] + minima[1] - 1 )/2; m_RegionIndex[2] -= (m_RegionSize[2] - maxima[2] + minima[2] - 1 )/2; ImageType::RegionType cropRegion(m_RegionIndex,m_RegionSize); origRegion.Crop(cropRegion); m_RegionSize[0] = origRegion.GetSize()[0]; m_RegionSize[1] = origRegion.GetSize()[1]; m_RegionSize[2] = origRegion.GetSize()[2]; m_RegionIndex[0] = origRegion.GetIndex()[0]; m_RegionIndex[1] = origRegion.GetIndex()[1]; m_RegionIndex[2] = origRegion.GetIndex()[2]; m_LowerBounds[0] = m_RegionIndex[0]; m_LowerBounds[1] = m_RegionIndex[1]; m_LowerBounds[2] = m_RegionIndex[2]; // It is assumed that the first and the last 3D images have the same LargestPossibleRegion. // If they have not, this will surely crash somewhere. m_UpperBounds[0] = inputItk->GetLargestPossibleRegion().GetSize()[0]-m_RegionSize[0]-m_RegionIndex[0]; m_UpperBounds[1] = inputItk->GetLargestPossibleRegion().GetSize()[1]-m_RegionSize[1]-m_RegionIndex[1]; m_UpperBounds[2] = inputItk->GetLargestPossibleRegion().GetSize()[2]-m_RegionSize[2]-m_RegionIndex[2]; } }
void mitk::AutoCropImageFilter::GenerateData | ( | ) | [protected, virtual] |
A version of GenerateData() specific for image processing filters.
This implementation will split the processing across multiple threads. The buffer is allocated by this method. Then the BeforeThreadedGenerateData() method is called (if provided). Then, a series of threads are spawned each calling ThreadedGenerateData(). After all the threads have completed processing, the AfterThreadedGenerateData() method is called (if provided). If an image processing filter cannot be threaded, the filter should provide an implementation of GenerateData(). That implementation is responsible for allocating the output buffer. If a filter an be threaded, it should NOT provide a GenerateData() method but should provide a ThreadedGenerateData() instead.
Reimplemented from mitk::ImageSource.
Definition at line 161 of file mitkAutoCropImageFilter.cpp.
References AccessFixedDimensionByItk_1, MITK_ERROR, and mitk::ImageTimeSelector::New().
{ mitk::Image::ConstPointer input = this->GetInput(); mitk::Image::Pointer output = this->GetOutput(); if(input.IsNull()) return; if(input->GetDimension() <= 2) { MITK_ERROR << "Only 3D and 4D images supported"; return; } if((output->IsInitialized()==false) ) return; if( m_TimeSelector.IsNull() ) m_TimeSelector = mitk::ImageTimeSelector::New(); m_TimeSelector->SetInput(input); mitk::SlicedData::RegionType outputRegion = input->GetRequestedRegion(); int tstart = outputRegion.GetIndex(3); int tmax = tstart + outputRegion.GetSize(3); for( int timestep=tstart;timestep<tmax;++timestep ) { m_TimeSelector->SetTimeNr(timestep); m_TimeSelector->UpdateLargestPossibleRegion(); AccessFixedDimensionByItk_1( m_TimeSelector->GetOutput(), ITKCrop3DImage, 3, timestep ); } // this->GetOutput()->Update(); // Not sure if this is necessary... m_TimeOfHeaderInitialization.Modified(); }
void mitk::AutoCropImageFilter::GenerateInputRequestedRegion | ( | ) | [protected, virtual] |
What is the input requested region that is required to produce the output requested region? The base assumption for image processing filters is that the input requested region can be set to match the output requested region. If a filter requires more input (for instance a filter that uses neighborhoods needs more input than output to avoid introducing artificial boundary conditions) or less input (for instance a magnify filter) will have to override this method. In doing so, it should call its superclass' implementation as its first step. Note that this imaging filters operate differently than the classes to this point in the class hierachy. Up till now, the base assumption has been that the largest possible region will be requested of the input.
Reimplemented from mitk::ImageToImageFilter.
Definition at line 330 of file mitkAutoCropImageFilter.cpp.
{ }
void mitk::AutoCropImageFilter::GenerateOutputInformation | ( | void | ) | [protected, virtual] |
Definition at line 77 of file mitkAutoCropImageFilter.cpp.
References mitk::TimeSlicedGeometry::CopyTimes(), mitk::TimeSlicedGeometry::InitializeEvenlyTimed(), MITK_ERROR, and mitk::Geometry3D::SetOrigin().
{ mitk::Image::Pointer input = const_cast< mitk::Image * > ( this->GetInput() ); if(input->GetDimension() <= 2) { MITK_ERROR << "Only 3D any 4D images are supported." << std::endl; return; } ComputeNewImageBounds(); // mitk::Image::ConstPointer input = this->GetInput(); mitk::Image::Pointer output = this->GetOutput(); if ((output->IsInitialized()) && (output->GetPipelineMTime() <= m_TimeOfHeaderInitialization.GetMTime())) return; itkDebugMacro(<<"GenerateOutputInformation()"); // PART I: initialize input requested region. We do this already here (and not // later when GenerateInputRequestedRegion() is called), because we // also need the information to setup the output. // pre-initialize input-requested-region to largest-possible-region // and correct time-region; spatial part will be cropped by // bounding-box of bounding-object below m_InputRequestedRegion = input->GetLargestPossibleRegion(); // build region out of bounding-box of cropping region size mitk::SlicedData::IndexType index; index[0] = m_RegionIndex[0]; index[1] = m_RegionIndex[1]; index[2] = m_RegionIndex[2]; index[3] = m_InputRequestedRegion.GetIndex()[3]; index[4] = m_InputRequestedRegion.GetIndex()[4]; mitk::SlicedData::SizeType size; size[0] = m_RegionSize[0]; size[1] = m_RegionSize[1]; size[2] = m_RegionSize[2]; size[3] = m_InputRequestedRegion.GetSize()[3]; size[4] = m_InputRequestedRegion.GetSize()[4]; mitk::SlicedData::RegionType boRegion(index, size); // crop input-requested-region with cropping region computed from the image data if(m_InputRequestedRegion.Crop(boRegion)==false) { // crop not possible => do nothing: set time size to 0. size.Fill(0); m_InputRequestedRegion.SetSize(size); return; } // set input-requested-region, because we access it later in // GenerateInputRequestedRegion (there we just set the time) input->SetRequestedRegion(&m_InputRequestedRegion); // PART II: initialize output image unsigned int dimension = input->GetDimension(); unsigned int *dimensions = new unsigned int [dimension]; itk2vtk(m_InputRequestedRegion.GetSize(), dimensions); if(dimension>3) memcpy(dimensions+3, input->GetDimensions()+3, (dimension-3)*sizeof(unsigned int)); output->Initialize(mitk::PixelType( GetOutputPixelType() ), dimension, dimensions); delete [] dimensions; // Set the spacing output->GetGeometry()->SetIndexToWorldTransform( input->GetGeometry()->GetIndexToWorldTransform() ); output->SetSpacing( input->GetSlicedGeometry()->GetSpacing() ); // Position the output Image to match the corresponding region of the input image mitk::SlicedGeometry3D* slicedGeometry = output->GetSlicedGeometry(); const mitk::SlicedData::IndexType& start = m_InputRequestedRegion.GetIndex(); mitk::Point3D origin; vtk2itk(start, origin); input->GetSlicedGeometry()->IndexToWorld(origin, origin); slicedGeometry->SetOrigin(origin); mitk::TimeSlicedGeometry* timeSlicedGeometry = output->GetTimeSlicedGeometry(); timeSlicedGeometry->InitializeEvenlyTimed(slicedGeometry, output->GetDimension(3)); timeSlicedGeometry->CopyTimes(input->GetTimeSlicedGeometry()); m_TimeOfHeaderInitialization.Modified(); output->SetPropertyList(input->GetPropertyList()->Clone()); }
virtual float mitk::AutoCropImageFilter::GetBackgroundValue | ( | ) | const [virtual] |
virtual const char* mitk::AutoCropImageFilter::GetClassName | ( | ) | const [virtual] |
virtual float mitk::AutoCropImageFilter::GetMarginFactor | ( | ) | const [virtual] |
const std::type_info & mitk::AutoCropImageFilter::GetOutputPixelType | ( | ) | [virtual] |
Definition at line 335 of file mitkAutoCropImageFilter.cpp.
{ return *this->GetInput()->GetPixelType().GetTypeId(); }
void mitk::AutoCropImageFilter::ITKCrop3DImage | ( | itk::Image< TPixel, VImageDimension > * | inputItkImage, |
unsigned int | timestep | ||
) | [protected] |
Definition at line 44 of file mitkAutoCropImageFilter.cpp.
References mitk::CastToMitkImage(), mitk::StatusBar::DisplayErrorText(), mitk::StatusBar::GetInstance(), MITK_ERROR, mitkIpPicDescriptor, and mitk::Image::New().
{ if (inputItkImage == NULL) { mitk::StatusBar::GetInstance()->DisplayErrorText ("An internal error occurred. Can't convert Image. Please report to bugs@mitk.org"); MITK_ERROR << "image is NULL...returning" << std::endl; return; } typedef itk::Image< TPixel, VImageDimension > InternalImageType; typedef typename InternalImageType::Pointer InternalImagePointer; typedef itk::CropImageFilter<InternalImageType,InternalImageType> FilterType; typedef typename itk::CropImageFilter<InternalImageType,InternalImageType>::Pointer FilterPointer; InternalImagePointer outputItk = InternalImageType::New(); FilterPointer cropFilter = FilterType::New(); cropFilter->SetLowerBoundaryCropSize( m_LowerBounds ); cropFilter->SetUpperBoundaryCropSize( m_UpperBounds ); cropFilter->SetInput( inputItkImage ); cropFilter->Update(); outputItk = cropFilter->GetOutput(); outputItk->DisconnectPipeline(); mitk::Image::Pointer newMitkImage = mitk::Image::New(); mitk::CastToMitkImage( outputItk, newMitkImage ); mitkIpPicDescriptor* image3D = newMitkImage->GetVolumeData(0)->GetPicDescriptor(); this->GetOutput()->SetPicVolume( image3D , timestep ); }
static Pointer mitk::AutoCropImageFilter::New | ( | ) | [static] |
Method for creation through the object factory.
Reimplemented from mitk::SubImageSelector.
Referenced by QmitkSegmentationPostProcessing::AutocropSelected(), mitkAutoCropImageFilterTest(), mitk::AutoCropTool::ProcessOneWorkingData(), and QmitkAutocropAction::Run().
virtual void mitk::AutoCropImageFilter::SetBackgroundValue | ( | float | _arg ) | [virtual] |
void mitk::AutoCropImageFilter::SetCroppingRegion | ( | RegionType | overrideRegion ) |
Definition at line 340 of file mitkAutoCropImageFilter.cpp.
{ m_CroppingRegion = overrideRegion; m_OverrideCroppingRegion = true; }
virtual void mitk::AutoCropImageFilter::SetMarginFactor | ( | float | _arg ) | [virtual] |
float mitk::AutoCropImageFilter::m_BackgroundValue [protected] |
Definition at line 104 of file mitkAutoCropImageFilter.h.
Definition at line 106 of file mitkAutoCropImageFilter.h.
Definition at line 122 of file mitkAutoCropImageFilter.h.
CropFilterType::SizeType mitk::AutoCropImageFilter::m_LowerBounds [protected] |
Definition at line 117 of file mitkAutoCropImageFilter.h.
float mitk::AutoCropImageFilter::m_MarginFactor [protected] |
Definition at line 108 of file mitkAutoCropImageFilter.h.
bool mitk::AutoCropImageFilter::m_OverrideCroppingRegion [protected] |
Definition at line 125 of file mitkAutoCropImageFilter.h.
ImageType::RegionType::IndexType mitk::AutoCropImageFilter::m_RegionIndex [protected] |
Definition at line 115 of file mitkAutoCropImageFilter.h.
ImageType::RegionType::SizeType mitk::AutoCropImageFilter::m_RegionSize [protected] |
Definition at line 114 of file mitkAutoCropImageFilter.h.
itk::TimeStamp mitk::AutoCropImageFilter::m_TimeOfHeaderInitialization [protected] |
Definition at line 123 of file mitkAutoCropImageFilter.h.
mitk::ImageTimeSelector::Pointer mitk::AutoCropImageFilter::m_TimeSelector [protected] |
Definition at line 120 of file mitkAutoCropImageFilter.h.
CropFilterType::SizeType mitk::AutoCropImageFilter::m_UpperBounds [protected] |
Definition at line 118 of file mitkAutoCropImageFilter.h.