Preprocess::ImageType2D::Pointer Preprocess::ExtractSlice(ImageType3D::Pointer img, int slice) { int size1 = img->GetLargestPossibleRegion().GetSize()[0]; int size2 = img->GetLargestPossibleRegion().GetSize()[1]; int size3 = img->GetLargestPossibleRegion().GetSize()[2]; if(slice >= size3) return NULL; ImageType3D::IndexType extractStart = {{ 0,0,slice }}; ImageType3D::SizeType extractSize = {{ size1, size2, 0 }}; ImageType3D::RegionType extractRegion; extractRegion.SetSize( extractSize ); extractRegion.SetIndex( extractStart ); typedef itk::ExtractImageFilter< ImageType3D, ImageType2D > ExtractFilterType; ExtractFilterType::Pointer extract = ExtractFilterType::New(); extract->SetInput( img ); extract->SetExtractionRegion( extractRegion ); try { extract->Update(); } catch( itk::ExceptionObject & err ) { std::cerr << "ITK FILTER ERROR: " << err << std::endl ; } return extract->GetOutput(); }
int main( int argc, char *argv[] ) { if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; std::cerr << "Usage: " << argv[0]; std::cerr << " fixedImageFile movingImageFile "; std::cerr << " outputImagefile [differenceBeforeRegistration] "; std::cerr << " [differenceAfterRegistration] "; std::cerr << " [sliceBeforeRegistration] "; std::cerr << " [sliceDifferenceBeforeRegistration] "; std::cerr << " [sliceDifferenceAfterRegistration] "; std::cerr << " [sliceAfterRegistration] " << std::endl; return EXIT_FAILURE; } const unsigned int Dimension = 3; typedef float PixelType; typedef itk::Image< PixelType, Dimension > FixedImageType; typedef itk::Image< PixelType, Dimension > MovingImageType; // Software Guide : BeginLatex // // The Transform class is instantiated using the code below. The only // template parameter to this class is the representation type of the // space coordinates. // // \index{itk::Versor\-Rigid3D\-Transform!Instantiation} // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet // Software Guide : EndCodeSnippet typedef itk:: LinearInterpolateImageFunction< MovingImageType, double > InterpolatorType; typedef itk::ImageRegistrationMethod< FixedImageType, MovingImageType > RegistrationType; MetricType::Pointer metric = MetricType::New(); OptimizerType::Pointer optimizer = OptimizerType::New(); InterpolatorType::Pointer interpolator = InterpolatorType::New(); RegistrationType::Pointer registration = RegistrationType::New(); registration->SetMetric( metric ); registration->SetOptimizer( optimizer ); registration->SetInterpolator( interpolator ); // Software Guide : BeginLatex // // The transform object is constructed below and passed to the registration // method. // // \index{itk::Versor\-Rigid3D\-Transform!New()} // \index{itk::Versor\-Rigid3D\-Transform!Pointer} // \index{itk::Registration\-Method!SetTransform()} // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet TransformType::Pointer transform = TransformType::New(); registration->SetTransform( transform ); // Software Guide : EndCodeSnippet typedef itk::ImageFileReader< FixedImageType > FixedImageReaderType; typedef itk::ImageFileReader< MovingImageType > MovingImageReaderType; FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); fixedImageReader->SetFileName( argv[1] ); movingImageReader->SetFileName( argv[2] ); registration->SetFixedImage( fixedImageReader->GetOutput() ); registration->SetMovingImage( movingImageReader->GetOutput() ); fixedImageReader->Update(); registration->SetFixedImageRegion( fixedImageReader->GetOutput()->GetBufferedRegion() ); // Software Guide : BeginLatex // // The input images are taken from readers. It is not necessary here to // explicitly call \code{Update()} on the readers since the // \doxygen{CenteredTransformInitializer} will do it as part of its // computations. The following code instantiates the type of the // initializer. This class is templated over the fixed and moving image type // as well as the transform type. An initializer is then constructed by // calling the \code{New()} method and assigning the result to a smart // pointer. // // \index{itk::Centered\-Transform\-Initializer!Instantiation} // \index{itk::Centered\-Transform\-Initializer!New()} // \index{itk::Centered\-Transform\-Initializer!SmartPointer} // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet // Software Guide : BeginLatex // // Let's execute this example over some of the images available in the ftp // site // // \url{ftp://public.kitware.com/pub/itk/Data/BrainWeb} // // Note that the images in the ftp site are compressed in \code{.tgz} files. // You should download these files an uncompress them in your local system. // After decompressing and extracting the files you could take a pair of // volumes, for example the pair: // // \begin{itemize} // \item \code{brainweb1e1a10f20.mha} // \item \code{brainweb1e1a10f20Rot10Tx15.mha} // \end{itemize} // // The second image is the result of intentionally rotating the first image // by $10$ degrees around the origin and shifting it $15mm$ in $X$. The // registration takes $24$ iterations and produces: // // \begin{center} // \begin{verbatim} // [-6.03744e-05, 5.91487e-06, -0.0871932, 2.64659, -17.4637, -0.00232496] // \end{verbatim} // \end{center} // // That are interpreted as // // \begin{itemize} // \item Versor = $(-6.03744e-05, 5.91487e-06, -0.0871932)$ // \item Translation = $(2.64659, -17.4637, -0.00232496)$ millimeters // \end{itemize} // // This Versor is equivalent to a rotation of $9.98$ degrees around the $Z$ // axis. // // Note that the reported translation is not the translation of $(15.0,0.0,0.0)$ // that we may be naively expecting. The reason is that the // \code{VersorRigid3DTransform} is applying the rotation around the center // found by the \code{CenteredTransformInitializer} and then adding the // translation vector shown above. // // It is more illustrative in this case to take a look at the actual // rotation matrix and offset resulting form the $6$ parameters. // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet transform->SetParameters( finalParameters ); TransformType::MatrixType matrix = transform->GetMatrix(); TransformType::OffsetType offset = transform->GetOffset(); std::cout << "Matrix = " << std::endl << matrix << std::endl; std::cout << "Offset = " << std::endl << offset << std::endl; // Software Guide : EndCodeSnippet // Software Guide : BeginLatex // // The output of this print statements is // // \begin{center} // \begin{verbatim} // Matrix = // 0.984795 0.173722 2.23132e-05 // -0.173722 0.984795 0.000119257 // -1.25621e-06 -0.00012132 1 // // Offset = // [-15.0105, -0.00672343, 0.0110854] // \end{verbatim} // \end{center} // // From the rotation matrix it is possible to deduce that the rotation is // happening in the X,Y plane and that the angle is on the order of // $\arcsin{(0.173722)}$ which is very close to 10 degrees, as we expected. // // Software Guide : EndLatex // Software Guide : BeginLatex // // \begin{figure} // \center // \includegraphics[width=0.44\textwidth]{BrainProtonDensitySliceBorder20} // \includegraphics[width=0.44\textwidth]{BrainProtonDensitySliceR10X13Y17} // \itkcaption[CenteredTransformInitializer input images]{Fixed and moving image // provided as input to the registration method using // CenteredTransformInitializer.} // \label{fig:FixedMovingImageRegistration8} // \end{figure} // // // \begin{figure} // \center // \includegraphics[width=0.32\textwidth]{ImageRegistration8Output} // \includegraphics[width=0.32\textwidth]{ImageRegistration8DifferenceBefore} // \includegraphics[width=0.32\textwidth]{ImageRegistration8DifferenceAfter} // \itkcaption[CenteredTransformInitializer output images]{Resampled moving // image (left). Differences between fixed and moving images, before (center) // and after (right) registration with the // CenteredTransformInitializer.} // \label{fig:ImageRegistration8Outputs} // \end{figure} // // Figure \ref{fig:ImageRegistration8Outputs} shows the output of the // registration. The center image in this figure shows the differences // between the fixed image and the resampled moving image before the // registration. The image on the right side presents the difference between // the fixed image and the resampled moving image after the registration has // been performed. Note that these images are individual slices extracted // from the actual volumes. For details, look at the source code of this // example, where the ExtractImageFilter is used to extract a slice from the // the center of each one of the volumes. One of the main purposes of this // example is to illustrate that the toolkit can perform registration on // images of any dimension. The only limitations are, as usual, the amount of // memory available for the images and the amount of computation time that it // will take to complete the optimization process. // // \begin{figure} // \center // \includegraphics[height=0.32\textwidth]{ImageRegistration8TraceMetric} // \includegraphics[height=0.32\textwidth]{ImageRegistration8TraceAngle} // \includegraphics[height=0.32\textwidth]{ImageRegistration8TraceTranslations} // \itkcaption[CenteredTransformInitializer output plots]{Plots of the metric, // rotation angle, center of rotation and translations during the // registration using CenteredTransformInitializer.} // \label{fig:ImageRegistration8Plots} // \end{figure} // // Figure \ref{fig:ImageRegistration8Plots} shows the plots of the main // output parameters of the registration process. The metric values at every // iteration. The Z component of the versor is plotted as an indication of // how the rotation progress. The X,Y translation components of the // registration are plotted at every iteration too. // // Shell and Gnuplot scripts for generating the diagrams in // Figure~\ref{fig:ImageRegistration8Plots} are available in the directory // // \code{InsightDocuments/SoftwareGuide/Art} // // You are strongly encouraged to run the example code, since only in this // way you can gain a first hand experience with the behavior of the // registration process. Once again, this is a simple reflection of the // philosophy that we put forward in this book: // // \emph{If you can not replicate it, then it does not exist!}. // // We have seen enough published papers with pretty pictures, presenting // results that in practice are impossible to replicate. That is vanity, not // science. // // Software Guide : EndLatex typedef itk::ResampleImageFilter< MovingImageType, FixedImageType > ResampleFilterType; TransformType::Pointer finalTransform = TransformType::New(); finalTransform->SetCenter( transform->GetCenter() ); finalTransform->SetParameters( finalParameters ); finalTransform->SetFixedParameters( transform->GetFixedParameters() ); ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetTransform( finalTransform ); resampler->SetInput( movingImageReader->GetOutput() ); FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); resampler->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); resampler->SetOutputOrigin( fixedImage->GetOrigin() ); resampler->SetOutputSpacing( fixedImage->GetSpacing() ); resampler->SetOutputDirection( fixedImage->GetDirection() ); resampler->SetDefaultPixelValue( 100 ); typedef unsigned char OutputPixelType; typedef itk::Image< OutputPixelType, Dimension > OutputImageType; typedef itk::CastImageFilter< FixedImageType, OutputImageType > CastFilterType; typedef itk::ImageFileWriter< OutputImageType > WriterType; WriterType::Pointer writer = WriterType::New(); CastFilterType::Pointer caster = CastFilterType::New(); writer->SetFileName( argv[3] ); caster->SetInput( resampler->GetOutput() ); writer->SetInput( caster->GetOutput() ); writer->Update(); typedef itk::SubtractImageFilter< FixedImageType, FixedImageType, FixedImageType > DifferenceFilterType; DifferenceFilterType::Pointer difference = DifferenceFilterType::New(); typedef itk::RescaleIntensityImageFilter< FixedImageType, OutputImageType > RescalerType; RescalerType::Pointer intensityRescaler = RescalerType::New(); intensityRescaler->SetInput( difference->GetOutput() ); intensityRescaler->SetOutputMinimum( 0 ); intensityRescaler->SetOutputMaximum( 255 ); difference->SetInput1( fixedImageReader->GetOutput() ); difference->SetInput2( resampler->GetOutput() ); resampler->SetDefaultPixelValue( 1 ); WriterType::Pointer writer2 = WriterType::New(); writer2->SetInput( intensityRescaler->GetOutput() ); // Compute the difference image between the // fixed and resampled moving image. if( argc > 5 ) { writer2->SetFileName( argv[5] ); writer2->Update(); } typedef itk::IdentityTransform< double, Dimension > IdentityTransformType; IdentityTransformType::Pointer identity = IdentityTransformType::New(); // Compute the difference image between the // fixed and moving image before registration. if( argc > 4 ) { resampler->SetTransform( identity ); writer2->SetFileName( argv[4] ); writer2->Update(); } // // Here we extract slices from the input volume, and the difference volumes // produced before and after the registration. These slices are presented as // figures in the Software Guide. // // typedef itk::Image< OutputPixelType, 2 > OutputSliceType; typedef itk::ExtractImageFilter< OutputImageType, OutputSliceType > ExtractFilterType; ExtractFilterType::Pointer extractor = ExtractFilterType::New(); extractor->SetDirectionCollapseToSubmatrix(); extractor->InPlaceOn(); FixedImageType::RegionType inputRegion = fixedImage->GetLargestPossibleRegion(); FixedImageType::SizeType size = inputRegion.GetSize(); FixedImageType::IndexType start = inputRegion.GetIndex(); // Select one slice as output size[2] = 0; start[2] = 90; FixedImageType::RegionType desiredRegion; desiredRegion.SetSize( size ); desiredRegion.SetIndex( start ); extractor->SetExtractionRegion( desiredRegion ); typedef itk::ImageFileWriter< OutputSliceType > SliceWriterType; SliceWriterType::Pointer sliceWriter = SliceWriterType::New(); sliceWriter->SetInput( extractor->GetOutput() ); if( argc > 6 ) { extractor->SetInput( caster->GetOutput() ); resampler->SetTransform( identity ); sliceWriter->SetFileName( argv[6] ); sliceWriter->Update(); } if( argc > 7 ) { extractor->SetInput( intensityRescaler->GetOutput() ); resampler->SetTransform( identity ); sliceWriter->SetFileName( argv[7] ); sliceWriter->Update(); } if( argc > 8 ) { resampler->SetTransform( finalTransform ); sliceWriter->SetFileName( argv[8] ); sliceWriter->Update(); } if( argc > 9 ) { extractor->SetInput( caster->GetOutput() ); resampler->SetTransform( finalTransform ); sliceWriter->SetFileName( argv[9] ); sliceWriter->Update(); } return EXIT_SUCCESS; }
void QmitkDenoisingView::StartDenoising() { if (!m_ThreadIsRunning) { if (m_ImageNode.IsNotNull()) { m_LastProgressCount = 0; switch (m_SelectedFilter) { case NOFILTERSELECTED: { break; } case NLM: { // initialize NLM m_InputImage = dynamic_cast<DiffusionImageType*> (m_ImageNode->GetData()); m_NonLocalMeansFilter = NonLocalMeansDenoisingFilterType::New(); if (m_BrainMaskNode.IsNotNull()) { // use brainmask if set m_ImageMask = dynamic_cast<mitk::Image*>(m_BrainMaskNode->GetData()); itk::Image<DiffusionPixelType, 3>::Pointer itkMask; mitk::CastToItkImage(m_ImageMask, itkMask); m_NonLocalMeansFilter->SetInputMask(itkMask); itk::ImageRegionIterator< itk::Image<DiffusionPixelType, 3> > mit(itkMask, itkMask->GetLargestPossibleRegion()); mit.GoToBegin(); itk::Image<DiffusionPixelType, 3>::IndexType minIndex; itk::Image<DiffusionPixelType, 3>::IndexType maxIndex; minIndex.Fill(10000); maxIndex.Fill(0); while (!mit.IsAtEnd()) { if (mit.Get()) { // calculation of the start & end index of the smallest masked region minIndex[0] = minIndex[0] < mit.GetIndex()[0] ? minIndex[0] : mit.GetIndex()[0]; minIndex[1] = minIndex[1] < mit.GetIndex()[1] ? minIndex[1] : mit.GetIndex()[1]; minIndex[2] = minIndex[2] < mit.GetIndex()[2] ? minIndex[2] : mit.GetIndex()[2]; maxIndex[0] = maxIndex[0] > mit.GetIndex()[0] ? maxIndex[0] : mit.GetIndex()[0]; maxIndex[1] = maxIndex[1] > mit.GetIndex()[1] ? maxIndex[1] : mit.GetIndex()[1]; maxIndex[2] = maxIndex[2] > mit.GetIndex()[2] ? maxIndex[2] : mit.GetIndex()[2]; } ++mit; } itk::Image<DiffusionPixelType, 3>::SizeType size; size[0] = maxIndex[0] - minIndex[0] + 1; size[1] = maxIndex[1] - minIndex[1] + 1; size[2] = maxIndex[2] - minIndex[2] + 1; m_MaxProgressCount = size[0] * size[1] * size[2]; } else { // initialize the progressbar m_MaxProgressCount = m_InputImage->GetDimension(0) * m_InputImage->GetDimension(1) * m_InputImage->GetDimension(2); } mitk::ProgressBar::GetInstance()->AddStepsToDo(m_MaxProgressCount); m_NonLocalMeansFilter->SetInputImage(m_InputImage->GetVectorImage()); m_NonLocalMeansFilter->SetUseRicianAdaption(m_Controls->m_RicianCheckbox->isChecked()); m_NonLocalMeansFilter->SetUseJointInformation(m_Controls->m_JointInformationCheckbox->isChecked()); m_NonLocalMeansFilter->SetSearchRadius(m_Controls->m_SpinBoxParameter1->value()); m_NonLocalMeansFilter->SetComparisonRadius(m_Controls->m_SpinBoxParameter2->value()); m_NonLocalMeansFilter->SetVariance(m_Controls->m_DoubleSpinBoxParameter3->value()); // start denoising in detached thread m_DenoisingThread.start(QThread::HighestPriority); break; } case GAUSS: { // initialize GAUSS and run m_InputImage = dynamic_cast<DiffusionImageType*> (m_ImageNode->GetData()); ExtractFilterType::Pointer extractor = ExtractFilterType::New(); extractor->SetInput(m_InputImage->GetVectorImage()); ComposeFilterType::Pointer composer = ComposeFilterType::New(); for (unsigned int i = 0; i < m_InputImage->GetVectorImage()->GetVectorLength(); ++i) { extractor->SetIndex(i); extractor->Update(); m_GaussianFilter = GaussianFilterType::New(); m_GaussianFilter->SetVariance(m_Controls->m_SpinBoxParameter1->value()); if (m_BrainMaskNode.IsNotNull()) { m_ImageMask = dynamic_cast<mitk::Image*>(m_BrainMaskNode->GetData()); itk::Image<DiffusionPixelType, 3>::Pointer itkMask = itk::Image<DiffusionPixelType, 3>::New(); mitk::CastToItkImage(m_ImageMask, itkMask); itk::MaskImageFilter<itk::Image<DiffusionPixelType, 3> , itk::Image<DiffusionPixelType, 3> >::Pointer maskImageFilter = itk::MaskImageFilter<itk::Image<DiffusionPixelType, 3> , itk::Image<DiffusionPixelType, 3> >::New(); maskImageFilter->SetInput(extractor->GetOutput()); maskImageFilter->SetMaskImage(itkMask); maskImageFilter->Update(); m_GaussianFilter->SetInput(maskImageFilter->GetOutput()); } else { m_GaussianFilter->SetInput(extractor->GetOutput()); } m_GaussianFilter->Update(); composer->SetInput(i, m_GaussianFilter->GetOutput()); } composer->Update(); DiffusionImageType::Pointer image = DiffusionImageType::New(); image->SetVectorImage(composer->GetOutput()); image->SetReferenceBValue(m_InputImage->GetReferenceBValue()); image->SetDirections(m_InputImage->GetDirections()); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_ImageNode->GetName().c_str(); imageNode->SetName((name+"_gauss_"+QString::number(m_Controls->m_SpinBoxParameter1->value())).toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode); break; } } } } else { m_NonLocalMeansFilter->AbortGenerateDataOn(); m_CompletedCalculation = false; } }
int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("DmriDenoising"); parser.setCategory("Preprocessing Tools"); parser.setDescription("dMRI denoising tool"); parser.setContributor("MIC"); parser.setArgumentPrefix("--", "-"); parser.beginGroup("1. Mandatory arguments:"); parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input); parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output); parser.addArgument("type", "", mitkCommandLineParser::Int, "Type:", "0 (TotalVariation), 1 (Gauss), 2 (NLM)", 0); parser.endGroup(); parser.beginGroup("2. Total variation parameters:"); parser.addArgument("tv_iterations", "", mitkCommandLineParser::Int, "Iterations:", "", 1); parser.addArgument("lambda", "", mitkCommandLineParser::Float, "Lambda:", "", 0.1); parser.endGroup(); parser.beginGroup("3. Gauss parameters:"); parser.addArgument("variance", "", mitkCommandLineParser::Float, "Variance:", "", 1.0); parser.endGroup(); parser.beginGroup("4. NLM parameters:"); parser.addArgument("nlm_iterations", "", mitkCommandLineParser::Int, "Iterations:", "", 4); parser.addArgument("sampling_radius", "", mitkCommandLineParser::Int, "Sampling radius:", "", 4); parser.addArgument("patch_radius", "", mitkCommandLineParser::Int, "Patch radius:", "", 1); parser.addArgument("num_patches", "", mitkCommandLineParser::Int, "Num. patches:", "", 10); parser.endGroup(); std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv); if (parsedArgs.size()==0) return EXIT_FAILURE; // mandatory arguments std::string imageName = us::any_cast<std::string>(parsedArgs["i"]); std::string outImage = us::any_cast<std::string>(parsedArgs["o"]); int type = 0; if (parsedArgs.count("type")) type = us::any_cast<int>(parsedArgs["type"]); int tv_iterations = 1; if (parsedArgs.count("tv_iterations")) tv_iterations = us::any_cast<int>(parsedArgs["tv_iterations"]); float lambda = 0.1; if (parsedArgs.count("lambda")) lambda = us::any_cast<float>(parsedArgs["lambda"]); float variance = 1.0; if (parsedArgs.count("variance")) variance = us::any_cast<float>(parsedArgs["variance"]); int nlm_iterations = 4; if (parsedArgs.count("nlm_iterations")) nlm_iterations = us::any_cast<int>(parsedArgs["nlm_iterations"]); int sampling_radius = 4; if (parsedArgs.count("sampling_radius")) sampling_radius = us::any_cast<int>(parsedArgs["sampling_radius"]); int patch_radius = 1; if (parsedArgs.count("patch_radius")) patch_radius = us::any_cast<int>(parsedArgs["patch_radius"]); int num_patches = 10; if (parsedArgs.count("num_patches")) num_patches = us::any_cast<int>(parsedArgs["num_patches"]); try { mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {}); mitk::Image::Pointer input_image = mitk::IOUtil::Load<mitk::Image>(imageName, &functor); typedef short DiffusionPixelType; typedef itk::VectorImage<DiffusionPixelType, 3> DwiImageType; typedef itk::Image<DiffusionPixelType, 3> DwiVolumeType; typedef itk::DiscreteGaussianImageFilter < DwiVolumeType, DwiVolumeType > GaussianFilterType; typedef itk::PatchBasedDenoisingImageFilter < DwiVolumeType, DwiVolumeType > NlmFilterType; typedef itk::VectorImageToImageFilter < DiffusionPixelType > ExtractFilterType; typedef itk::ComposeImageFilter < itk::Image<DiffusionPixelType, 3> > ComposeFilterType; if (!mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(input_image)) mitkThrow() << "Input is not a diffusion-weighted image!"; DwiImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(input_image); mitk::Image::Pointer denoised_image = nullptr; switch (type) { case 0: { ComposeFilterType::Pointer composer = ComposeFilterType::New(); for (unsigned int i=0; i<itkVectorImagePointer->GetVectorLength(); ++i) { ExtractFilterType::Pointer extractor = ExtractFilterType::New(); extractor->SetInput( itkVectorImagePointer ); extractor->SetIndex( i ); extractor->Update(); DwiVolumeType::Pointer gradient_volume = extractor->GetOutput(); itk::TotalVariationDenoisingImageFilter< DwiVolumeType, DwiVolumeType >::Pointer filter = itk::TotalVariationDenoisingImageFilter< DwiVolumeType, DwiVolumeType >::New(); filter->SetInput(gradient_volume); filter->SetLambda(lambda); filter->SetNumberIterations(tv_iterations); filter->Update(); composer->SetInput(i, filter->GetOutput()); } composer->Update(); denoised_image = mitk::GrabItkImageMemory(composer->GetOutput()); break; } case 1: { ExtractFilterType::Pointer extractor = ExtractFilterType::New(); extractor->SetInput( itkVectorImagePointer ); ComposeFilterType::Pointer composer = ComposeFilterType::New(); for (unsigned int i = 0; i < itkVectorImagePointer->GetVectorLength(); ++i) { extractor->SetIndex(i); extractor->Update(); GaussianFilterType::Pointer filter = GaussianFilterType::New(); filter->SetVariance(variance); filter->SetInput(extractor->GetOutput()); filter->Update(); composer->SetInput(i, filter->GetOutput()); } composer->Update(); denoised_image = mitk::GrabItkImageMemory(composer->GetOutput()); break; } case 2: { typedef itk::Statistics::GaussianRandomSpatialNeighborSubsampler< NlmFilterType::PatchSampleType, DwiVolumeType::RegionType > SamplerType; // sampling the image to find similar patches SamplerType::Pointer sampler = SamplerType::New(); sampler->SetRadius( sampling_radius ); sampler->SetVariance( sampling_radius*sampling_radius ); sampler->SetNumberOfResultsRequested( num_patches ); MITK_INFO << "Starting NLM denoising"; ExtractFilterType::Pointer extractor = ExtractFilterType::New(); extractor->SetInput( itkVectorImagePointer ); ComposeFilterType::Pointer composer = ComposeFilterType::New(); for (unsigned int i = 0; i < itkVectorImagePointer->GetVectorLength(); ++i) { extractor->SetIndex(i); extractor->Update(); NlmFilterType::Pointer filter = NlmFilterType::New(); filter->SetInput(extractor->GetOutput()); filter->SetPatchRadius(patch_radius); filter->SetNoiseModel(NlmFilterType::RICIAN); filter->UseSmoothDiscPatchWeightsOn(); filter->UseFastTensorComputationsOn(); filter->SetNumberOfIterations(nlm_iterations); filter->SetSmoothingWeight( 1 ); filter->SetKernelBandwidthEstimation(true); filter->SetSampler( sampler ); filter->Update(); composer->SetInput(i, filter->GetOutput()); MITK_INFO << "Gradient " << i << " finished"; } composer->Update(); denoised_image = mitk::GrabItkImageMemory(composer->GetOutput()); break; } } mitk::DiffusionPropertyHelper::SetGradientContainer(denoised_image, mitk::DiffusionPropertyHelper::GetGradientContainer(input_image)); mitk::DiffusionPropertyHelper::SetReferenceBValue(denoised_image, mitk::DiffusionPropertyHelper::GetReferenceBValue(input_image)); mitk::DiffusionPropertyHelper::InitializeImage( denoised_image ); std::string ext = itksys::SystemTools::GetFilenameExtension(outImage); if (ext==".nii" || ext==".nii.gz") mitk::IOUtil::Save(denoised_image, "DWI_NIFTI", outImage); else mitk::IOUtil::Save(denoised_image, outImage); } catch (itk::ExceptionObject e) { std::cout << e; return EXIT_FAILURE; } catch (std::exception e) { std::cout << e.what(); return EXIT_FAILURE; } catch (...) { std::cout << "ERROR!?!"; return EXIT_FAILURE; } return EXIT_SUCCESS; }
void Focus::MakeVarianceImage() { UCharImageType::Pointer img; if(imgIn) img = imgIn; else { typedef itk::RGBToLuminanceImageFilter< RGBImageType, UCharImageType > ConvertFilterType; ConvertFilterType::Pointer convert = ConvertFilterType::New(); convert->SetInput( imgInColor ); convert->Update(); img = convert->GetOutput(); } typedef itk::VarianceImageFunction< UCharImageType2D > VarianceFunctionType; typedef itk::ExtractImageFilter< UCharImageType, UShortImageType2D > ExtractFilterType; std::cout << "Making Variance Image"; int size1 = (int)img->GetLargestPossibleRegion().GetSize()[0]; int size2 = (int)img->GetLargestPossibleRegion().GetSize()[1]; int size3 = (int)img->GetLargestPossibleRegion().GetSize()[2]; varImg = FloatImageType::New(); FloatImageType::PointType origin; origin[0] = 0; origin[1] = 0; origin[2] = 0; varImg->SetOrigin( origin ); FloatImageType::IndexType start = {{ 0,0,0 }}; FloatImageType::SizeType size = {{ size1, size2, size3 }}; FloatImageType::RegionType region; region.SetSize( size ); region.SetIndex( start ); varImg->SetRegions( region ); varImg->Allocate(); for(int z = 0; z < size3; ++z) { std::cout << "."; UCharImageType::IndexType index = { {0,0,z} }; UCharImageType::SizeType size = { {size1, size2, 0} }; UCharImageType::RegionType region; region.SetSize(size); region.SetIndex(index); ExtractFilterType::Pointer extract = ExtractFilterType::New(); extract->SetInput( img ); extract->SetExtractionRegion( region ); extract->Update(); UShortImageType2D::Pointer im2 = extract->GetOutput(); typedef itk::MeanImageFilter<UShortImageType2D,UShortImageType2D> MeanFilterType; typedef itk::SquareImageFilter<UShortImageType2D,UShortImageType2D> SquareFilterType; typedef itk::SubtractImageFilter<UShortImageType2D,UShortImageType2D> SubtractFilterType; UShortImageType2D::SizeType radiussize = {{radius, radius}}; MeanFilterType::Pointer mean1 = MeanFilterType::New(); mean1->SetInput(im2); mean1->SetRadius(radiussize); SquareFilterType::Pointer sq1 = SquareFilterType::New(); sq1->SetInput(mean1->GetOutput()); SquareFilterType::Pointer sq2 = SquareFilterType::New(); sq2->SetInput(im2); MeanFilterType::Pointer mean2 = MeanFilterType::New(); mean2->SetInput(sq2->GetOutput()); mean2->SetRadius(radiussize); SubtractFilterType::Pointer sb1 = SubtractFilterType::New(); sb1->SetInput1(mean2->GetOutput()); sb1->SetInput2(sq1->GetOutput()); sb1->Update(); typedef itk::ImageRegionIterator<FloatImageType> FloatIteratorType; typedef itk::ImageRegionIterator<UShortImageType2D> UShortIteratorType; FloatIteratorType fit(varImg,region); UShortIteratorType uit(sb1->GetOutput(),sb1->GetOutput()->GetLargestPossibleRegion()); for(fit.GoToBegin(),uit.GoToBegin();!uit.IsAtEnd(); ++fit, ++uit) { //printf("%d ", int(uit.Get())); fit.Set(uit.Get()); } /* // DONT USE THIS BECAUSE IT IS VERY SLOW VarianceFunctionType::Pointer varFunction = VarianceFunctionType::New(); varFunction->SetInputImage( im2 ); varFunction->SetNeighborhoodRadius( radius ); for(int x=0; x<size1; ++x) { for(int y=0; y<size2; ++y) { UCharImageType2D::IndexType ind; ind[0] = x; ind[1] = y; float var = (float)varFunction->EvaluateAtIndex( ind ); FloatImageType::IndexType ind3; ind3[0] = x; ind3[1] = y; ind3[2] = z; varImg->SetPixel(ind3, var); } } */ } typedef itk::ImageFileWriter<FloatImageType> FloatWriter; FloatWriter::Pointer fwriter = FloatWriter::New(); fwriter->SetInput(varImg); fwriter->SetFileName("test_fwriter.mhd"); fwriter->Update(); /* //Rescale: typedef itk::RescaleIntensityImageFilter< FloatImageType, UCharImageType > RescaleType; RescaleType::Pointer rescale = RescaleType::New(); rescale->SetOutputMaximum( 255 ); rescale->SetOutputMinimum( 0 ); rescale->SetInput( varImg ); rescale->Update(); */ std::cout << "done\n"; }