std::vector<cleaver::AbstractScalarField*> NRRDTools::segmentationToIndicatorFunctions(std::string filename, double sigma) { // read file using ITK if (filename.find(".nrrd") != std::string::npos) { itk::NrrdImageIOFactory::RegisterOneFactory(); } else if (filename.find(".mha") != std::string::npos) { itk::MetaImageIOFactory::RegisterOneFactory(); } ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(filename); reader->Update(); ImageType::Pointer image = reader->GetOutput(); //determine the number of labels in the segmentations ImageCalculatorFilterType::Pointer imageCalculatorFilter = ImageCalculatorFilterType::New(); imageCalculatorFilter->SetImage(reader->GetOutput()); imageCalculatorFilter->Compute(); auto maxLabel = static_cast<size_t>(imageCalculatorFilter->GetMaximum()); auto minLabel = static_cast<size_t>(imageCalculatorFilter->GetMinimum()); std::vector<cleaver::AbstractScalarField*> fields; //extract images from each label for an indicator function for (size_t i = minLabel, num = 0; i <= maxLabel; i++, num++) { //pull out this label ThreshType::Pointer thresh = ThreshType::New(); thresh->SetInput(image); thresh->SetOutsideValue(0); thresh->ThresholdOutside(static_cast<double>(i) - 0.001, static_cast<double>(i) + 0.001); thresh->Update(); //change the values to be from 0 to 1 MultiplyImageFilterType::Pointer multiplyImageFilter = MultiplyImageFilterType::New(); multiplyImageFilter->SetInput(thresh->GetOutput()); multiplyImageFilter->SetConstant(1. / static_cast<double>(i)); multiplyImageFilter->Update(); //do some blurring GaussianBlurType::Pointer blur = GaussianBlurType::New(); blur->SetInput(multiplyImageFilter->GetOutput()); blur->SetVariance(sigma * sigma); blur->Update(); //find the average value between ImageCalculatorFilterType::Pointer calc = ImageCalculatorFilterType::New(); calc->SetImage(blur->GetOutput()); calc->Compute(); float mx = calc->GetMaximum(); float mn = calc->GetMinimum(); auto md = (mx + mn) / 2.f; //create a distance map with that minimum value as the levelset DMapType::Pointer dm = DMapType::New(); dm->SetInput(blur->GetOutput()); dm->SetInsideValue(md + 0.1f); dm->SetOutsideValue(md -0.1f); dm->Update(); //MultiplyImageFilterType::Pointer mult = // MultiplyImageFilterType::New(); //mult->SetInput(blur->GetOutput()); //mult->SetConstant(-20. / (mx - mn)); //mult->Update(); /*SubtractImageFilterType::Pointer subtractFilter = SubtractImageFilterType::New(); subtractFilter->SetInput1(mult->GetOutput()); subtractFilter->SetConstant2(1.); subtractFilter->Update();*/ //convert the image to a cleaver "abstract field" auto img = dm->GetOutput(); auto region = img->GetLargestPossibleRegion(); auto numPixel = region.GetNumberOfPixels(); float *data = new float[numPixel]; auto x = region.GetSize()[0], y = region.GetSize()[1], z = region.GetSize()[2]; fields.push_back(new cleaver::FloatField(data, x, y, z)); auto beg = filename.find_last_of("/") + 1; auto name = filename.substr(beg, filename.size() - beg); auto fin = name.find_last_of("."); name = name.substr(0, fin); std::stringstream ss; ss << name << i; fields[num]->setName(ss.str()); itk::ImageRegionConstIterator<ImageType> imageIterator(img, region); size_t pixel = 0; while (!imageIterator.IsAtEnd()) { // Get the value of the current pixel float val = static_cast<float>(imageIterator.Get()); ((cleaver::FloatField*)fields[num])->data()[pixel++] = -val; ++imageIterator; } auto spacing = img->GetSpacing(); ((cleaver::FloatField*)fields[num])->setScale( cleaver::vec3(spacing[0], spacing[1], spacing[2])); //NRRDTools::saveNRRDFile(fields[num], "a" + std::to_string(num)); } return fields; }
bool AcceptMatch(VertexDescriptorType target, VertexDescriptorType source, float& computedEnergy) const override { itk::Index<2> targetPixel = ITKHelpers::CreateIndex(target); itk::ImageRegion<2> targetRegion = ITKHelpers::GetRegionInRadiusAroundPixel(targetPixel, HalfWidth); itk::Index<2> sourcePixel = ITKHelpers::CreateIndex(source); itk::ImageRegion<2> sourceRegion = ITKHelpers::GetRegionInRadiusAroundPixel(sourcePixel, HalfWidth); typedef itk::Image<float, 2> FloatImageType; typedef itk::VectorMagnitudeImageFilter<TImage, FloatImageType> VectorMagnitudeFilterType; typename VectorMagnitudeFilterType::Pointer magnitudeFilter = VectorMagnitudeFilterType::New(); magnitudeFilter->SetInput(Image); magnitudeFilter->Update(); std::vector<itk::Offset<2> > validOffsets = MaskImage->GetValidOffsetsInRegion(targetRegion); FloatImageType::Pointer sourceImage = FloatImageType::New(); // sourceImage->SetRegions(ITKHelpers::CornerRegion(sourceRegion.GetSize())); // sourceImage->Allocate(); ITKHelpers::ExtractRegion(magnitudeFilter->GetOutput(), sourceRegion, sourceImage.GetPointer()); FloatImageType::Pointer targetImage = FloatImageType::New(); // sourceImage->SetRegions(ITKHelpers::CornerRegion(targetRegion.GetSize())); // sourceImage->Allocate(); ITKHelpers::ExtractRegion(magnitudeFilter->GetOutput(), targetRegion, targetImage.GetPointer()); std::vector<itk::Index<2> > validIndices = ITKHelpers::OffsetsToIndices(validOffsets); VarianceFunctor varianceFunctor; AverageFunctor averageFunctor; /////////// Target region ////////// std::vector<FloatImageType::PixelType> validPixelsTargetRegion = ITKHelpers::GetPixelValues(targetImage.GetPointer(), validIndices); typename TypeTraits<FloatImageType::PixelType>::LargerType targetMean = averageFunctor(validPixelsTargetRegion); typename TypeTraits<FloatImageType::PixelType>::LargerType targetStandardDeviation = sqrt(varianceFunctor(validPixelsTargetRegion)); typedef itk::AddImageFilter <FloatImageType, FloatImageType, FloatImageType> AddImageFilterType; AddImageFilterType::Pointer targetAddImageFilter = AddImageFilterType::New(); targetAddImageFilter->SetInput(targetImage); targetAddImageFilter->SetConstant2(-1.0f * targetMean); targetAddImageFilter->Update(); typedef itk::MultiplyImageFilter<FloatImageType, FloatImageType, FloatImageType> MultiplyImageFilterType; MultiplyImageFilterType::Pointer targetMultiplyImageFilter = MultiplyImageFilterType::New(); targetMultiplyImageFilter->SetInput(targetImage); targetMultiplyImageFilter->SetConstant(1.0f/targetStandardDeviation); targetMultiplyImageFilter->Update(); /////////// Source region ////////// std::vector<FloatImageType::PixelType> validPixelsSourceRegion = ITKHelpers::GetPixelValues(sourceImage.GetPointer(), validIndices); typename TypeTraits<FloatImageType::PixelType>::LargerType sourceMean = averageFunctor(validPixelsSourceRegion); typename TypeTraits<FloatImageType::PixelType>::LargerType sourceStandardDeviation = sqrt(varianceFunctor(validPixelsSourceRegion)); AddImageFilterType::Pointer sourceAddImageFilter = AddImageFilterType::New(); sourceAddImageFilter->SetInput(sourceImage); sourceAddImageFilter->SetConstant2(-1.0f * sourceMean); sourceAddImageFilter->Update(); MultiplyImageFilterType::Pointer sourceMultiplyImageFilter = MultiplyImageFilterType::New(); sourceMultiplyImageFilter->SetInput(sourceImage); sourceMultiplyImageFilter->SetConstant(1.0f/sourceStandardDeviation); sourceMultiplyImageFilter->Update(); // Initialize computedEnergy = 0.0f; for(std::vector<itk::Index<2> >::const_iterator iter = validIndices.begin(); iter != validIndices.end(); ++iter) { computedEnergy += (sourceMultiplyImageFilter->GetOutput()->GetPixel(*iter) * targetMultiplyImageFilter->GetOutput()->GetPixel(*iter)); } computedEnergy /= static_cast<float>(validIndices.size()); if(computedEnergy < Threshold) { std::cout << this->VisitorName << ": Match accepted (" << computedEnergy << " is less than " << Threshold << ")" << std::endl << std::endl; return true; } else { std::cout << this->VisitorName << ": Match rejected (" << computedEnergy << " is greater than " << Threshold << ")" << std::endl << std::endl; return false; } };