void WorkbenchUtils::resampleImageItk(itk::Image <PixelType, ImageDimension> *itkImage, Interpolator interpolType, unsigned int *newDimensions, Image::Pointer outImage) { typedef itk::Image <PixelType, ImageDimension> ImageType; // get original image informations const typename ImageType::RegionType &inputRegion = itkImage->GetLargestPossibleRegion(); const typename ImageType::SizeType &inputDimensions = inputRegion.GetSize(); const typename ImageType::SpacingType &inputSpacing = itkImage->GetSpacing(); // calculate spacing double outputSpacing[ImageDimension]; itk::Size <ImageDimension> outputSize; for (unsigned int i = 0; i < ImageDimension; ++i) { outputSpacing[i] = inputSpacing[i] * (double) inputDimensions[i] / newDimensions[i]; outputSize[i] = newDimensions[i]; } // transform typedef itk::IdentityTransform<double, ImageDimension> TransformType; typename TransformType::Pointer transform = TransformType::New(); transform->SetIdentity(); // interpolator typedefs typedef double CoordinateType; typedef itk::LinearInterpolateImageFunction <ImageType, CoordinateType> LinearInterpolatorType; typedef itk::NearestNeighborInterpolateImageFunction <ImageType, CoordinateType> NearestNeighborInterpolatorType; typedef itk::GaussianInterpolateImageFunction <ImageType, CoordinateType> GaussianInterpolatorType; typedef itk::BSplineInterpolateImageFunction <ImageType, CoordinateType> BSplineInterpolatorType; // set up the filter typedef itk::ResampleImageFilter <ImageType, ImageType> ResampleFilterType; typename ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New(); resampleFilter->SetTransform(transform); resampleFilter->SetOutputOrigin(itkImage->GetOrigin()); resampleFilter->SetOutputSpacing(outputSpacing); resampleFilter->SetSize(outputSize); switch (interpolType) { case Interpolator::LINEAR: // the default; resampleFilter->SetInterpolator(LinearInterpolatorType::New()); break; case Interpolator::NEAREST_NEIGHBOR: resampleFilter->SetInterpolator(NearestNeighborInterpolatorType::New()); break; case Interpolator::GAUSSIAN: resampleFilter->SetInterpolator(GaussianInterpolatorType::New()); break; case Interpolator::BSPLINE: resampleFilter->SetInterpolator(BSplineInterpolatorType::New()); break; } resampleFilter->SetInput(itkImage); resampleFilter->UpdateLargestPossibleRegion(); // get the results and cast them back to mitk. return via out parameter. outImage->InitializeByItk(resampleFilter->GetOutput()); CastToMitkImage(resampleFilter->GetOutput(), outImage); }
/** * @brief 3D resample data to new grid size * * @param M Incoming data * @param f Resampling factor in all 3 dimensions * @param im Interpolation method (LINEAR|BSPLINE) * * @return Resampled data */ template<class T> static Matrix<T> resample (const Matrix<T>& M, const Matrix<double>& f, const InterpMethod& im) { Matrix <T> res = M; #ifdef HAVE_INSIGHT typedef typename itk::OrientedImage< T, 3 > InputImageType; typedef typename itk::OrientedImage< T, 3 > OutputImageType; typedef typename itk::IdentityTransform< double, 3 > TransformType; typedef typename itk::LinearInterpolateImageFunction< InputImageType, double > InterpolatorType; typedef typename itk::ResampleImageFilter< InputImageType, InputImageType > ResampleFilterType; typename InterpolatorType::Pointer linterp = InterpolatorType::New(); TransformType::Pointer trafo = TransformType::New(); trafo->SetIdentity(); typename InputImageType::SpacingType space; space[0] = 1.0/f[0]; space[1] = 1.0/f[1]; space[2] = 1.0/f[2]; typedef typename InputImageType::SizeType::SizeValueType SizeValueType; typename InputImageType::SizeType size; size[0] = static_cast<SizeValueType>(res.Dim(0)); size[1] = static_cast<SizeValueType>(res.Dim(1)); size[2] = static_cast<SizeValueType>(res.Dim(2)); typename itk::OrientedImage< T, 3 >::Pointer input = itk::OrientedImage< T, 3 >::New(); typename itk::OrientedImage< T, 3 >::Pointer output = itk::OrientedImage< T, 3 >::New(); typename itk::Image< T, 3 >::IndexType ipos; ipos[0] = 0; ipos[1] = 0; ipos[2] = 0; typename itk::Image< T, 3 >::IndexType opos; opos[0] = 0; opos[1] = 0; opos[2] = 0; typename itk::Image< T, 3 >::RegionType ireg; ireg.SetSize(size); ireg.SetIndex(ipos); input->SetRegions(ireg); input->Allocate(); typename itk::Image< T, 3 >::RegionType oreg; oreg.SetSize(size); ireg.SetIndex(opos); output->SetRegions(oreg); output->Allocate(); for (size_t z = 0; z < res.Dim(2); z++) for (size_t y = 0; y < res.Dim(1); y++) for (size_t x = 0; x < res.Dim(0); x++) { ipos[0] = x; ipos[1] = y; ipos[2] = z; input->SetPixel (ipos, res.At(x,y,z)); } typename ResampleFilterType::Pointer rs = ResampleFilterType::New(); rs->SetInput( input ); rs->SetTransform( trafo ); rs->SetInterpolator( linterp ); rs->SetOutputOrigin ( input->GetOrigin()); rs->SetOutputSpacing ( space ); rs->SetOutputDirection ( input->GetDirection()); rs->SetSize ( size ); rs->Update (); output = rs->GetOutput(); res = Matrix<T> (res.Dim(0)*f[0], res.Dim(1)*f[1], res.Dim(2)*f[2]); res.Res(0) = res.Res(0)/f[0]; res.Res(1) = res.Dim(1)/f[1]; res.Res(2) = res.Dim(2)/f[2]; for (size_t z = 0; z < res.Dim(2); z++) for (size_t y = 0; y < res.Dim(1); y++) for (size_t x = 0; x < res.Dim(0); x++) { opos[0] = x; opos[1] = y; opos[2] = z; res.At(x,y,z) = output->GetPixel (opos); } #else printf ("ITK ERROR - Resampling not performed without ITK!\n"); #endif return res; }
void udgPerfusionEstimator<TPerfuImage,TMaskImage, TTransform>::ComputeEstimation() { if(m_perfuImage.IsNull()){ std::cout<<"Not Perfusion Image defined"<<std::endl; return; } if(m_ventricleMask.IsNull()){ std::cout<<"Not Ventricle Mask Image defined"<<std::endl; return; } if(m_strokeMask.IsNull()){ std::cout<<"Not Stroke Mask Image defined"<<std::endl; return; } if(m_Transform.IsNull()){ std::cout<<"Not Transform defined"<<std::endl; return; } m_estimatedImage = PerfuImageType::New(); m_estimatedImage->SetRegions( m_perfuImage->GetLargestPossibleRegion() ); m_estimatedImage->SetSpacing( m_perfuImage->GetSpacing() ); m_estimatedImage->SetOrigin( m_perfuImage->GetOrigin() ); m_estimatedImage->Allocate(); //Definim la regi�molt probablement infartada typename MaskImageType::Pointer m_strokeInfluence = MaskImageType::New(); m_strokeInfluence->SetRegions( m_strokeMask->GetLargestPossibleRegion() ); m_strokeInfluence->SetSpacing( m_strokeMask->GetSpacing() ); m_strokeInfluence->SetOrigin( m_strokeMask->GetOrigin() ); m_strokeInfluence->Allocate(); typename DilateFilterType::Pointer binaryDilate = DilateFilterType::New(); binaryDilate->SetDilateValue( 255 ); //suposem que el valor alt ser�255 StructuringElementType structuringElementDilate; structuringElementDilate.SetRadius( 2 ); // 3x3 structuring element structuringElementDilate.CreateStructuringElement(); binaryDilate->SetKernel( structuringElementDilate ); binaryDilate->SetInput( m_strokeMask ); binaryDilate->Update(); m_strokeInfluence = binaryDilate->GetOutput(); //Fi regi�molt probablement infartada typename ResampleFilterType::Pointer resample = ResampleFilterType::New(); typename TransformType::Pointer inverse = TransformType::New(); if (!m_Transform->GetInverse( inverse )) { std::cout<<"ERROR! udgPerfusionEstimator<TPerfuImage,TMaskImage, TTransform>::ComputeEstimation() No hi ha inversa!"<<std::endl; } resample->SetTransform( inverse ); resample->SetInput( m_ventricleMask); resample->SetSize( m_perfuImage->GetLargestPossibleRegion().GetSize() ); resample->SetOutputOrigin( m_perfuImage->GetOrigin() ); resample->SetOutputSpacing( m_perfuImage->GetSpacing() ); resample->SetDefaultPixelValue( 0 ); resample->SetInterpolator( m_InterpolatorVentricle ); resample->Update(); Ventricles = resample->GetOutput(); typename ResampleFilterType::Pointer resample2 = ResampleFilterType::New(); resample2->SetTransform( inverse ); resample2->SetInput( m_strokeInfluence); resample2->SetSize( m_perfuImage->GetLargestPossibleRegion().GetSize() ); resample2->SetOutputOrigin( m_perfuImage->GetOrigin() ); resample2->SetOutputSpacing( m_perfuImage->GetSpacing() ); resample2->SetDefaultPixelValue( 0 ); resample2->SetInterpolator( m_InterpolatorStroke ); resample2->Update(); //Creem les finestres mostrant les imatges registrades Stroke = resample2->GetOutput(); PerfuIteratorType estimatedIt(m_estimatedImage, m_estimatedImage->GetBufferedRegion()); PerfuIteratorType perfuIt(m_perfuImage, m_perfuImage->GetBufferedRegion()); PerfuIteratorType VentIt(Ventricles, Ventricles->GetBufferedRegion()); PerfuIteratorType StkIt(Stroke, Stroke->GetBufferedRegion()); RadiusNeighborType radius; radius.Fill(2); m_InterpolatorVentricle->SetInputImage( m_ventricleMask ); m_InterpolatorStroke->SetInputImage( m_strokeInfluence ); PerfuPointType inputPoint; PerfuPixelType perfuValue; PerfuPixelType VentValue; PerfuPixelType StkValue; typename PerfuImageType::IndexType index; MaskPointType transformedPoint; perfuIt.GoToBegin(); VentIt.GoToBegin(); StkIt.GoToBegin(); estimatedIt.GoToBegin(); ++perfuIt; ++VentIt; ++StkIt; ++estimatedIt; while (!perfuIt.IsAtEnd()) { perfuValue = perfuIt.Value(); // if(perfuValue == 0) // ((maskValue == m_insideValue)&&(perfuValue == 0)) if ( perfuValue < 32 ) // ((maskValue == m_insideValue)&&(perfuValue == 0)) { //és a dir, és un punt negre index = perfuIt.GetIndex(); m_perfuImage->TransformIndexToPhysicalPoint(index, inputPoint); transformedPoint = m_Transform->TransformPoint(inputPoint); //transformed point és el punt corresponent en difusió if (m_InterpolatorVentricle->IsInsideBuffer(transformedPoint)) { // m_Interpolator->SetInputImage( m_ventricleMask ); //const RealType VentriclemaskValue = m_InterpolatorVentricle->Evaluate(transformedPoint); VentValue = VentIt.Value(); // if(VentriclemaskValue!=0) if(VentValue!=0) { estimatedIt.Set(0);//estimatedIt.Set(1); } else { /* const RealType strokemaskValue = m_InterpolatorStroke->Evaluate(transformedPoint); if(strokemaskValue!=0){ estimatedIt.Set(1);//estimatedIt.Set(255); } */ StkValue = StkIt.Value(); if(StkValue != 0) { estimatedIt.Set(255); } else { estimatedIt.Set(0); } } } } else { estimatedIt.Set( perfuValue ); //estimatedIt.Set( perfuValue ); } ++perfuIt; ++VentIt; ++StkIt; ++estimatedIt; } //Aqu�determinem els punts que no s� ni infart ni ventricle, fent una mitjana dels valors veins //La imatge s'actualitza sobre ella mateixa, per�no sembla que aix�hagi de portar problemes /* double med, cont; PerfuNeighborIteratorType perfuNeighborIt(radius, m_estimatedImage, m_estimatedImage->GetBufferedRegion()); perfuNeighborIt.GoToBegin(); perfuIt.GoToBegin(); estimatedIt.GoToBegin(); ++perfuNeighborIt; ++estimatedIt; while (!estimatedIt.IsAtEnd()) { perfuValue = estimatedIt.Get(); if (perfuValue == 0) //� a dir, � un punt negre { med=0; cont=0; for (unsigned int i = 0; i < perfuNeighborIt.Size(); i++) { if ( perfuNeighborIt.GetPixel(i) != 0 && perfuNeighborIt.GetPixel(i)<1000 ) { med += perfuNeighborIt.GetPixel(i); cont ++; } } estimatedIt.Set(static_cast<PerfuPixelType> (med/cont)); } ++perfuNeighborIt; ++estimatedIt; } */ //Suavitzem la sortida --> S'hauria de fer per�d�a errors /* typename SmoothingFilterType::Pointer smoothFilter = SmoothingFilterType::New(); // smoothFilter->SetInput(m_estimatedImage); smoothFilter->SetInput(m_perfuImage); // smoothFilter->SetNumberOfIterations(5); // smoothFilter->SetTimeStep(0.0625); // smoothFilter->SetConductanceParameter(1); //std::cout<<"hola 1"<<std::endl; smoothFilter->SetVariance(1); smoothFilter->SetMaximumKernelWidth(6); //smoothFilter->Update(); RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); rescaler->SetOutputMinimum( 0 ); rescaler->SetOutputMaximum( 255 ); //std::cout<<"hola 2"<<std::endl; rescaler->SetInput(smoothFilter->GetOutput()); rescaler->Update(); //std::cout<<"hola 3"<<std::endl; m_estimatedImage = rescaler->GetOutput(); */ }