From f181e8fc01dec00bc6b0c82e0e273e1bb0d292c5 Mon Sep 17 00:00:00 2001 From: srit Date: Wed, 20 Oct 2010 15:01:03 +0000 Subject: [PATCH] Implemented new vvImage scheme: the itk to vtk image converter is now kept as a class member for improved memory handling. --- common/vvFromITK.h | 52 +++++++-------------------------- common/vvImage.cxx | 50 ------------------------------- common/vvImage.h | 10 +++---- common/vvImage.txx | 31 ++++++++++++++++++++ vv/vvImageReader.txx | 24 +++++---------- vv/vvLabelImageLoaderWidget.cxx | 48 ++++++++++++------------------ 6 files changed, 72 insertions(+), 143 deletions(-) create mode 100755 common/vvImage.txx diff --git a/common/vvFromITK.h b/common/vvFromITK.h index 8187051..c7178fe 100644 --- a/common/vvFromITK.h +++ b/common/vvFromITK.h @@ -23,7 +23,6 @@ // itk #include -#include //------------------------------------------------------------------------------ /**Converts the itk image to vv, handling the 4D problem @@ -38,31 +37,27 @@ template vvImage::Pointer vvImageFromITK(type if (Dim == 4 || time_sequence) //The time sequence case: create a series of VTK images { - typedef itk::Image< PixelType, Dim - 1 > ConnectorImageType; - typedef itk::ImageToVTKImageFilter ConnectorType; - typedef itk::ExtractImageFilter FilterType; - - typename FilterType::Pointer filter = FilterType::New(); - typename ConnectorType::Pointer connector = ConnectorType::New(); + typedef itk::Image< PixelType, Dim - 1 > ItkImageType; + typedef itk::ExtractImageFilter FilterType; //extract the 3D slices and put them in a std::vector typename InputImageType::RegionType inputRegion = input->GetLargestPossibleRegion(); typename InputImageType::SizeType inputSize = inputRegion.GetSize(); - + typename InputImageType::IndexType start = inputRegion.GetIndex(); typename InputImageType::SizeType extractedRegionSize = inputSize; typename InputImageType::RegionType extractedRegion; extractedRegionSize[Dim - 1] = 0; extractedRegion.SetSize(extractedRegionSize); - filter->SetInput(input); - connector->SetInput(filter->GetOutput()); - - typename InputImageType::IndexType start = inputRegion.GetIndex(); - for (unsigned int i = 0; i < inputSize[Dim - 1]; i++) { start[Dim - 1] = i; extractedRegion.SetIndex(start); + + typename FilterType::Pointer filter = FilterType::New(); filter->SetExtractionRegion(extractedRegion); + filter->SetInput(input); + filter->ReleaseDataFlagOn(); + try { filter->Update(); } @@ -71,39 +66,14 @@ template vvImage::Pointer vvImageFromITK(type << " " << err << std::endl; return vv_image; } - try { - connector->Update(); - } - catch ( itk::ExceptionObject & err ) { - std::cerr << "Error while setting vvImage from ITK (Dim==4) [Connect phase]" - << " " << err << std::endl; - return vv_image; - } - vtkImageData *image = vtkImageData::New(); - image->DeepCopy(connector->GetOutput()); - vv_image->AddImage(image); + vv_image->AddItkImage(filter->GetOutput()); } vv_image->SetTimeSpacing(input->GetSpacing()[Dim-1]); - vv_image->SetTimeOrigin(input->GetOrigin()[Dim-1]); + vv_image->SetTimeOrigin(input->GetOrigin()[Dim-1]); } else //Dim == 1,2,3 and not time_sequence { - typedef itk::Image< PixelType, Dim > ConnectorImageType; - typedef itk::ImageToVTKImageFilter ConnectorType; - typename ConnectorType::Pointer connector = ConnectorType::New(); - connector->SetInput(input); - - try { - connector->Update(); - } - catch ( itk::ExceptionObject & err ) { - std::cerr << "Error while setting vvImage from ITK (Dim==3)" - << " " << err << std::endl; - return vv_image; - } - vtkImageData *image = vtkImageData::New(); - image->DeepCopy(connector->GetOutput()); - vv_image->AddImage(image); + vv_image->AddItkImage(input); } return vv_image; } diff --git a/common/vvImage.cxx b/common/vvImage.cxx index 79f2381..c5a3af7 100644 --- a/common/vvImage.cxx +++ b/common/vvImage.cxx @@ -54,13 +54,6 @@ vvImage::~vvImage() //-------------------------------------------------------------------- void vvImage::Reset() { - for (unsigned int i = 0; i < mVtkImages.size(); i++) -#ifdef NO_RESLICE - mVtkImages[i]->Delete(); -#else - mVtkImageReslice[i]->GetInput()->Delete(); -#endif - mVtkImages.resize(0); mVtkImageReslice.resize(0); @@ -68,35 +61,6 @@ void vvImage::Reset() } //-------------------------------------------------------------------- -//-------------------------------------------------------------------- -void vvImage::SetImage(std::vector< vtkImageData* > images) -{ - Reset(); - for (unsigned int i = 0; i < images.size(); i++) - AddImage(images[i]); -} -//-------------------------------------------------------------------- - - -//-------------------------------------------------------------------- -void vvImage::AddImage(vtkImageData* image) -{ -#ifdef NO_RESLICE - mVtkImages.push_back(image); - return; -#endif - - mVtkImageReslice.push_back(vtkSmartPointer::New()); - mVtkImageReslice.back()->SetInterpolationModeToLinear(); - mVtkImageReslice.back()->AutoCropOutputOn(); - mVtkImageReslice.back()->SetBackgroundColor(-1000,-1000,-1000,1); - mVtkImageReslice.back()->SetResliceTransform(mTransform); - mVtkImageReslice.back()->SetInput(0, image); - mVtkImageReslice.back()->Update(); - mVtkImages.push_back( mVtkImageReslice.back()->GetOutput(0) ); -} -//-------------------------------------------------------------------- - //-------------------------------------------------------------------- int vvImage::GetNumberOfSpatialDimensions() { @@ -288,18 +252,4 @@ void vvImage::UpdateReslice() } //-------------------------------------------------------------------- - -//-------------------------------------------------------------------- -vtkImageData * CopyAndCastToFloatFrom(vtkImageData * input) -{ - vtkImageData * p = vtkImageData::New(); - p->SetExtent(input->GetExtent ()); // Only first ! could not be 4D - p->SetScalarTypeToFloat(); - p->AllocateScalars(); - p->CopyAndCastFrom(input, input->GetExtent()); - return p; -} -//-------------------------------------------------------------------- - - #endif // VVIMAGE_CXX diff --git a/common/vvImage.h b/common/vvImage.h index 6a30a45..cc0ce76 100644 --- a/common/vvImage.h +++ b/common/vvImage.h @@ -21,6 +21,7 @@ #include #include #include +#include #include class vtkImageData; @@ -33,12 +34,12 @@ class vvImage : public itk::LightObject public : typedef vvImage Self; typedef itk::SmartPointer Pointer; + typedef itk::ProcessObject::Pointer ConverterPointer; itkNewMacro(Self); void Init(); void Reset(); - void SetImage(std::vector images); - void AddImage(vtkImageData* image); + template void AddItkImage(TItkImageType *input); const std::vector& GetVTKImages(); vtkImageData* GetFirstVTKImageData(); int GetNumberOfDimensions() const; @@ -63,6 +64,7 @@ private: vvImage(); ~vvImage(); + std::vector< ConverterPointer > mItkToVtkConverters; std::vector mVtkImages; std::vector< vtkSmartPointer > mVtkImageReslice; vtkSmartPointer mTransform; @@ -71,8 +73,6 @@ private: }; //------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -vtkImageData * CopyAndCastToFloatFrom(vtkImageData * p); -//------------------------------------------------------------------------------ +#include "vvImage.txx" #endif diff --git a/common/vvImage.txx b/common/vvImage.txx new file mode 100755 index 0000000..4532a68 --- /dev/null +++ b/common/vvImage.txx @@ -0,0 +1,31 @@ +#include + +//-------------------------------------------------------------------- +template +void vvImage::AddItkImage(TItkImageType *input) +{ + typedef itk::ImageToVTKImageFilter ConverterType; + typename ConverterType::Pointer converter = ConverterType::New(); + converter->SetInput(input); + + try { + converter->Update(); + } + catch ( itk::ExceptionObject & err ) { + std::cerr << "Error while setting vvImage from ITK" + << " " << err << std::endl; + } + mItkToVtkConverters.push_back(dynamic_cast< itk::ProcessObject *>(converter.GetPointer())); + mVtkImages.push_back(converter->GetOutput()); + + //mVtkImageReslice.push_back(vtkSmartPointer::New()); + //mVtkImageReslice.back()->SetInterpolationModeToLinear(); + //mVtkImageReslice.back()->AutoCropOutputOn(); + //mVtkImageReslice.back()->SetBackgroundColor(-1000,-1000,-1000,1); + //mVtkImageReslice.back()->SetResliceTransform(mTransform); + //mVtkImageReslice.back()->SetInput(0, image); + //mVtkImageReslice.back()->Update(); + //mVtkImages.push_back( mVtkImageReslice.back()->GetOutput(0) ); +} +//-------------------------------------------------------------------- + diff --git a/vv/vvImageReader.txx b/vv/vvImageReader.txx index 9393392..75fab2d 100644 --- a/vv/vvImageReader.txx +++ b/vv/vvImageReader.txx @@ -75,14 +75,12 @@ void vvImageReader::UpdateWithDimAndInputPixelType() // one at the time to avoid excessive // memory use { - typedef itk::Image< InputPixelType, VImageDimension-1 > InputImageType; - typedef itk::ImageFileReader ReaderType; - typename ReaderType::Pointer reader = ReaderType::New(); - typedef itk::ImageToVTKImageFilter ConnectorType; - typename ConnectorType::Pointer connector = ConnectorType::New(); - connector->SetInput(reader->GetOutput()); - mImage=vvImage::New(); - for (std::vector::const_iterator i=mInputFilenames.begin(); i!=mInputFilenames.end(); i++) { + mImage=vvImage::New(); + for (std::vector::const_iterator i=mInputFilenames.begin(); i!=mInputFilenames.end(); i++) { + typedef itk::Image< InputPixelType, VImageDimension-1 > InputImageType; + typedef itk::ImageFileReader ReaderType; + typename ReaderType::Pointer reader = ReaderType::New(); + reader->ReleaseDataFlagOn(); std::cout << (*i) << std::endl; reader->SetFileName(*i); try { @@ -95,15 +93,7 @@ void vvImageReader::UpdateWithDimAndInputPixelType() mLastError = error.str(); return; } - try { - connector->Update(); - } catch ( itk::ExceptionObject & err ) { - std::cerr << "Error while setting vvImage from ITK (MERGEDWITHTIME)" - << " " << err << std::endl; - } - vtkImageData *image = vtkImageData::New(); - image->ShallowCopy(connector->GetOutput()); - mImage->AddImage(image); + mImage->AddItkImage(reader->GetOutput()); } } else { if (mInputFilenames.size() > 1) { diff --git a/vv/vvLabelImageLoaderWidget.cxx b/vv/vvLabelImageLoaderWidget.cxx index 6c36d62..99b8a2f 100644 --- a/vv/vvLabelImageLoaderWidget.cxx +++ b/vv/vvLabelImageLoaderWidget.cxx @@ -19,6 +19,9 @@ #ifndef VVTOOLINPUTSELECTORWIDGET_CXX #define VVTOOLINPUTSELECTORWIDGET_CXX +// clitk +#include + // vv #include "vvLabelImageLoaderWidget.h" #include "vvSlicerManager.h" @@ -79,51 +82,36 @@ void vvLabelImageLoaderWidget::OpenImage() "",Extensions); //mMainWindow->GetInputPathName() if (filename == "") return; // nothing to do + itk::ImageIOBase::Pointer header = clitk::readImageHeader(filename.toStdString()); + // Open Image QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - vvImageReader * mReader = new vvImageReader; - mReader->SetInputFilename(filename.toStdString()); - mReader->Update(IMAGE); - if (mReader->GetLastError().size() != 0) { + if (!header) { std::cerr << "Error while reading " << filename.toStdString() << std::endl; - QString error = "Cannot open file \n"; - error += mReader->GetLastError().c_str(); + QString error = QString("Cannot open file %1\n").arg(filename); QMessageBox::information(this,tr("Reading problem"),error); - delete mReader; return; } // Create output pointer - m_Output = vvImage::New(); - - // Check type and convert if needed - vvImage::Pointer temp = mReader->GetOutput(); - - if (temp->GetNumberOfDimensions() != 3) { + if (header->GetNumberOfDimensions() != 3) { std::cerr << "Error while reading " << filename.toStdString() << std::endl; QString error; error = QString("Cannot open file %1 because it is not 3D\n").arg(filename); QMessageBox::information(this,tr("Reading problem"),error); - delete mReader; return; } - if (temp->GetScalarTypeAsITKString() != "unsigned_char") { - vtkImageData * p = vtkImageData::New(); - p->SetExtent(temp->GetFirstVTKImageData()->GetExtent ()); // Only first ! could not be 4D - p->SetScalarTypeToUnsignedChar(); - p->AllocateScalars (); - p->CopyAndCastFrom(temp->GetFirstVTKImageData(), temp->GetFirstVTKImageData()->GetExtent ()); - m_Output->AddImage(p); - vvImageWriter * writer = new vvImageWriter; - writer->SetOutputFileName("a.mhd"); - writer->SetInput(m_Output); - writer->Update(); - } - else { - m_Output = temp; - } - + // Convert to unsigned char while reading (if not already) + typedef itk::ImageFileReader< itk::Image< unsigned char, 3 > > ReaderType; + ReaderType::Pointer reader = ReaderType::New(); + reader->SetFileName(filename.toStdString()); + reader->Update(); + + // Create vv image + m_Output = vvImage::New(); + m_Output->AddItkImage( reader->GetOutput() ); + // Set GUI mLabelInputInfo->setText(vtksys::SystemTools::GetFilenameName(filename.toStdString()).c_str()); QApplication::restoreOverrideCursor(); -- 2.47.1