void LabelsVolumeGenerator::postProcessTargetITK() { typedef unsigned char PixelType; typedef Image<PixelType, 3> ImageType; // create a new image from the target data ImageType::Pointer input = ImageType::New(); ImageType::IndexType start; start.Fill(0); ImageType::SizeType size; for (int i = 0; i < 3; ++i) size[i] = m_targetVolume->dimensions[i]; ImageType::RegionType region; region.SetSize(size); region.SetIndex(start); input->SetRegions(region); input->SetSpacing(m_targetVolume->spacing.data()); input->Allocate(); memcpy(input->GetBufferPointer(), m_targetVolume->data, m_bufferSize); // create a grayscale dilation filter and a structuring element typedef BinaryBallStructuringElement<PixelType, 3> StructureType; typedef GrayscaleDilateImageFilter<ImageType, ImageType, StructureType> DilateFilterType; DilateFilterType::Pointer filter = DilateFilterType::New(); StructureType structure; structure.SetRadius(1); filter->SetKernel(structure); // set up progress reporting if (m_progressReporter) { CStyleCommand::Pointer command = CStyleCommand::New(); command->SetClientData(m_progressReporter); command->SetCallback(ProgressCallback); filter->AddObserver(ProgressEvent(), command); m_progressReporter->start("Post-Processing Label volume", "Dilating label field..."); } // hook up the filters and run filter->SetInput(input); filter->Update(); if (m_progressReporter) m_progressReporter->finish(); // copy back into the target volume data memcpy(m_targetVolume->data, filter->GetOutput()->GetBufferPointer(), m_bufferSize); // threshold and gaussian blur to put a smooth version into the alpha channel typedef BinaryThresholdImageFilter<ImageType, ImageType> ThresholderType; // typedef DiscreteGaussianImageFilter<ImageType, ImageType> SmoothFilterType; typedef SmoothingRecursiveGaussianImageFilter<ImageType, ImageType> SmoothFilterType; ThresholderType::Pointer thresholder = ThresholderType::New(); thresholder->SetLowerThreshold(1); thresholder->SetUpperThreshold(255); thresholder->SetInsideValue(255); thresholder->SetOutsideValue(0); SmoothFilterType::Pointer smoother = SmoothFilterType::New(); // smoother->SetVariance(0.05); // in physical units // smoother->SetMaximumKernelWidth(5); smoother->SetSigma(0.2); // set up progress reporting (again) if (m_progressReporter) { CStyleCommand::Pointer command = CStyleCommand::New(); command->SetClientData(m_progressReporter); command->SetCallback(ProgressCallback); smoother->AddObserver(ProgressEvent(), command); m_progressReporter->start("Post-Processing Label volume", "Smoothing alpha mask..."); } // hook up the filters and run thresholder->SetInput(input); smoother->SetInput(thresholder->GetOutput()); smoother->Update(); // copy back into the target volume data memcpy(m_targetMask->data, smoother->GetOutput()->GetBufferPointer(), m_bufferSize); if (m_progressReporter) m_progressReporter->finish(); }
int main(int, char ** argv) { // load the input nifti image std::string inputFolderName = argv[1]; std::string outputFilename = argv[2]; // get the set of images from the input folder QStringList nameFilters; nameFilters << "phiContour*_t=*_final.nii"; QDir inputFolder(QString::fromStdString(inputFolderName)); QStringList inputFiles = inputFolder.entryList(nameFilters); unsigned int numTimeSteps = inputFiles.size(); qSort(inputFiles.begin(), inputFiles.end(), file_sort); std::cout << "--> Found " << numTimeSteps << " segmentations" << std::endl; std::cout << "--> Loading images and thresholding " << std::endl; utils::LabelVolumeList labels; for(unsigned int i = 0; i < numTimeSteps; i++) { std::cout << "\t" << inputFiles[i].toStdString() << std::endl; typedef itk::Image<float,3> InputImageType; typedef itk::ImageFileReader<InputImageType> ReaderType; std::string filename = inputFolderName + "/" + inputFiles[i].toStdString(); ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(filename); reader->SetImageIO(itk::NiftiImageIO::New()); reader->Update(); typedef itk::BinaryThresholdImageFilter<InputImageType, utils::LabelVolume> ThresholderType; ThresholderType::Pointer thresholder = ThresholderType::New(); thresholder->SetInput(reader->GetOutput()); thresholder->SetOutsideValue(0); thresholder->SetInsideValue(1); thresholder->SetLowerThreshold(0); thresholder->SetUpperThreshold(255); thresholder->Update(); labels.push_back(thresholder->GetOutput()); } // build the output image typedef itk::Image<unsigned char, 4> OutputType; OutputType::Pointer output = OutputType::New(); typedef itk::JoinSeriesImageFilter<utils::LabelVolume, OutputType> JoinerType; JoinerType::Pointer joiner = JoinerType::New(); joiner->SetSpacing(1.0); joiner->SetOrigin(0); for(unsigned int i = 0; i < labels.size(); i++) { joiner->SetInput(i, labels[i]); } joiner->Update(); output = joiner->GetOutput(); // save the output typedef itk::ImageFileWriter<OutputType> WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetInput(output); writer->SetFileName(outputFilename); writer->Update(); /* utils::LabelVolume::Pointer ref = labels[0]; OutputType::SpacingType outSpacing; OutputType::DirectionType outDirection; outDirection.SetIdentity(); OutputType::PointType outOrigin; for(unsigned int i = 0; i < 3; i++) { outSpacing[i] = ref->GetSpacing()[i]; outOrigin[i] = ref->GetOrigin()[i]; } return 0; utils::LabelVolumeIO::Write(outputFilename, thresholder->GetOutput()); */ return 0; }