bool DilationFilter::execute() { ImagePtr input = this->getCopiedInputImage(); if (!input) return false; double radius = this->getDilationRadiusOption(mCopiedOptions)->getValue(); // Convert radius in mm to radius in voxels for the structuring element Eigen::Array3d spacing = input->getSpacing(); itk::Size<3> radiusInVoxels; radiusInVoxels[0] = radius/spacing(0); radiusInVoxels[1] = radius/spacing(1); radiusInVoxels[2] = radius/spacing(2); itkImageType::ConstPointer itkImage = AlgorithmHelper::getITKfromSSCImage(input); // Create structuring element typedef itk::BinaryBallStructuringElement<unsigned char,3> StructuringElementType; StructuringElementType structuringElement; structuringElement.SetRadius(radiusInVoxels); structuringElement.CreateStructuringElement(); // Dilation typedef itk::BinaryDilateImageFilter<itkImageType, itkImageType, StructuringElementType> dilateFilterType; dilateFilterType::Pointer dilationFilter = dilateFilterType::New(); dilationFilter->SetInput(itkImage); dilationFilter->SetKernel(structuringElement); dilationFilter->SetDilateValue(1); dilationFilter->Update(); itkImage = dilationFilter->GetOutput(); //Convert ITK to VTK itkToVtkFilterType::Pointer itkToVtkFilter = itkToVtkFilterType::New(); itkToVtkFilter->SetInput(itkImage); itkToVtkFilter->Update(); vtkImageDataPtr rawResult = vtkImageDataPtr::New(); rawResult->DeepCopy(itkToVtkFilter->GetOutput()); vtkImageCastPtr imageCast = vtkImageCastPtr::New(); imageCast->SetInputData(rawResult); imageCast->SetOutputScalarTypeToUnsignedChar(); imageCast->Update(); rawResult = imageCast->GetOutput(); // TODO: possible memory problem here - check debug mem system of itk/vtk mRawResult = rawResult; BoolPropertyPtr generateSurface = this->getGenerateSurfaceOption(mCopiedOptions); if (generateSurface->getValue()) { double threshold = 1;/// because the segmented image is 0..1 mRawContour = ContourFilter::execute(mRawResult, threshold); } return true; }
void Preprocess::ClosingFilter( int radius ) { typedef itk::BinaryBallStructuringElement<PixelType,3> StructuringElementType; typedef itk::GrayscaleMorphologicalClosingImageFilter<ImageType3D, ImageType3D, StructuringElementType > FilterType; FilterType::Pointer close = FilterType::New(); StructuringElementType structuringElement; structuringElement.CreateStructuringElement(); structuringElement.SetRadius(radius); close->SetKernel( structuringElement ); close->SetInput(myImg); try { close->Update(); } catch( itk::ExceptionObject & err ) { std::cerr << "Exception caught: " << err << std::endl; } myImg = close->GetOutput(); }
void LidarSegmentationWidget::on_btnErodeSources_clicked() { Mask::Pointer sourcesImage = Mask::New(); sourcesImage->SetRegions(this->ImageRegion); ITKHelpers::IndicesToBinaryImage(this->Sources, sourcesImage); typedef itk::BinaryBallStructuringElement<Mask::PixelType,2> StructuringElementType; StructuringElementType structuringElementBig; structuringElementBig.SetRadius(3); structuringElementBig.CreateStructuringElement(); typedef itk::BinaryErodeImageFilter<Mask, Mask, StructuringElementType> BinaryErodeImageFilterType; BinaryErodeImageFilterType::Pointer erodeFilter = BinaryErodeImageFilterType::New(); erodeFilter->SetInput(sourcesImage); erodeFilter->SetKernel(structuringElementBig); erodeFilter->Update(); //this->Sources.clear(); this->Sources = ITKHelpers::GetNonZeroPixels(erodeFilter->GetOutput()); UpdateSelections(); }
void TrainPipeline::Train(){ int limitValue = 0; int label = NULL; FILE* resultFile; ProgressBar progressBar; //string resultFileName = "results.txt"; resultFile = fopen(this -> resultFileName.c_str(), "w"); FileHandler* fileHandler = new FileHandler(dirName); //fprintf(resultFile, "%d\n" , fileHandler -> GetNumberOfFiles()); for (int cont = 0; cont < fileHandler -> GetNumberOfFiles(); cont++) { /* --------------------------------------- IMAGE CONVERTING --------------------------------------------- */ RGBReaderType::Pointer rgbReader = RGBReaderType::New(); rgbReader -> SetFileName(fileHandler -> GetFiles()[cont]); //rgbReader -> SetFileName("img/Im148_0.tif"); // teste uma imagem //label = descobreLabel("img/Im148_0.tif"); LabelFinder* labelFinder = new LabelFinder(fileHandler -> GetFiles()[cont]); label = labelFinder -> GetLabel(); //label = descobreLabel(fileHandler -> GetFiles()[cont]); rgbReader -> SetFileName(fileHandler -> GetFiles()[cont]); GrayscaleFilterType::Pointer grayscaleFilter = GrayscaleFilterType::New(); grayscaleFilter -> SetInput(rgbReader -> GetOutput()); GrayscaleImageType::Pointer grayScaleImage = grayscaleFilter -> GetOutput(); grayscaleFilter -> Update(); /* ------------------------------------------------------------------------------------------------------ */ /* ------------------------------------------- OPENING MORPHOLOGY -------------------------------------------- */ StructuringElementType structuringElementOpen; structuringElementOpen.SetRadius(5); structuringElementOpen.CreateStructuringElement(); OpeningMorphologyType::Pointer openingFilter = OpeningMorphologyType::New(); openingFilter -> SetInput(grayscaleFilter -> GetOutput()); openingFilter -> SetKernel(structuringElementOpen); //stringstream imageOutOpen; //imageOutOpen << "open_" << imageName; //cout << "imageName : " << imageOutOpen.str() << endl; //WriterType::Pointer writerOpen = WriterType::New(); //writerOpen -> SetFileName(imageOutOpen.str()); //writerOpen -> SetInput(openingFilter -> GetOutput()); //writerOpen -> Update(); /* ------------------------------------------------------------------------------------------------------ */ /* ------------------------------------------- FIND THRESHOLD VALUE -------------------------------------- */ Optimalthreshold* optimalThreshold = new Optimalthreshold(openingFilter -> GetOutput()); //Optimalthreshold* optimalThreshold = new Optimalthreshold(grayscaleFilter -> GetOutput()); limitValue = optimalThreshold -> GetOutput(); //cout << "Valor Limiar : " << limitValue << endl; ThresholdFilter::Pointer thresholdFilter = ThresholdFilter::New(); thresholdFilter -> SetInput(grayscaleFilter -> GetOutput()); thresholdFilter -> SetOutsideValue(255); thresholdFilter -> SetUpper(optimalThreshold -> GetOutput()); // valor aleatorio thresholdFilter -> SetLower(0); thresholdFilter -> Update(); GrayscaleImageType::Pointer thresholdImage = GrayscaleImageType::New(); thresholdImage = thresholdFilter -> GetOutput(); thresholdImage -> Update(); /* ------------------------------------------------------------------------------------------------------ */ /* ---------------------------------------- REGION GROWING ---------------------------------------------- */ NeighborhoodConnectedFilterType::Pointer regionGrow = NeighborhoodConnectedFilterType::New(); float lower = 0; float upper = optimalThreshold -> GetOutput(); regionGrow->SetLower(lower); regionGrow->SetUpper(upper); regionGrow->SetReplaceValue(255); regionGrow->SetInput(grayscaleFilter -> GetOutput()); for (int x = 5; x < 250; x += 5) { GrayscaleImageType::IndexType seed1; seed1[0] = x; seed1[1] = 0; regionGrow->AddSeed(seed1); GrayscaleImageType::IndexType seed2; seed2[0] = x; seed2[1] = 255; regionGrow->AddSeed(seed2); } for (int y = 0; y < 250; y += 5) { GrayscaleImageType::IndexType seed1; seed1[0] = 255; seed1[1] = y; regionGrow->AddSeed(seed1); GrayscaleImageType::IndexType seed2; seed2[0] = 0; seed2[1] = y; regionGrow->AddSeed(seed2); } /* ------------------------------------------------------------------------------------------------------ */ /* --------------------------------------------- OR IMAGEFILTER ----------------------------------------- */ OrFilterType::Pointer orFilter = OrFilterType::New(); orFilter -> SetInput(0, thresholdImage); orFilter -> SetInput(1, regionGrow -> GetOutput()); orFilter -> Update(); /* ------------------------------------------------------------------------------------------------------- */ /* --------------------------------------------- DATA COLLECT -------------------------------------------- */ //DataCollector* dataCollector = new DataCollector(dilateFilter -> GetOutput()); DataCollector* dataCollector = new DataCollector(orFilter -> GetOutput()); /* ------------------------------------------------------------------------------------------------------- */ /* ------------------------------------------ GENERATE RESULTS ------------------------------------------- * stringstream imageOut; imageOut << "out/" << fileHandler -> GetFiles()[cont].substr(dirName.length() , (fileHandler -> GetFiles()[cont].length() - dirName.length())); cout << "imageName : " << imageOut.str() << endl; cout << "==============================================================================" << endl << endl; WriterType::Pointer writer = WriterType::New(); writer -> SetFileName(imageOut.str()); writer -> SetInput(orFilter -> GetOutput()); writer -> Update(); /* ------------------------------------------------------------------------------------------------------- */ if(dataCollector -> GetPxCount() == 0){ //fprintf(resultFile,"%d , %d , %d , %d\n",limitValue * 2 , dataCollector -> GetPxCount() , dataCollector -> GetCellAvrage() , label); fprintf(resultFile,"%d , %d , %d , %d\n",limitValue * 2 , dataCollector -> GetCellAvrage() , dataCollector -> GetAberration() , label); }else{ //fprintf(resultFile,"%d , %d , %d , %d\n",limitValue , dataCollector -> GetPxCount() / 100 , dataCollector -> GetCellAvrage() , label); fprintf(resultFile,"%d , %d , %d , %d\n",limitValue , dataCollector -> GetCellAvrage() , dataCollector -> GetAberration() , label); } //cout << "tot : " << fileHandler -> GetNumberOfFiles() << " | inc : " << (100 / (float) fileHandler -> GetNumberOfFiles()) << endl; progressBar.update(100 / (float) fileHandler -> GetNumberOfFiles()); progressBar.print(); //cout << "Processado " << cont + 1 << " de " << fileHandler -> GetNumberOfFiles() << endl; } fclose(resultFile); /* -------------------------------------------------------------------------------------------------------- */ cout << "TREINAMENTO CONCLUIDO" << endl; }
float rich_cell:: compute_average_intensity( ImageType::Pointer intensity_image, LabelImageType::ConstPointer label_image, int dist_interior, int dist_exterior) { float sum_interior = 0; float sum_exterior = 0; int count_interior = 0; int count_exterior = 0; if (dist_exterior < dist_interior) { // the entire segmented area is taken for (unsigned int b = 0; b<all_points_.size(); b++) { vnl_vector_fixed< float, 3 > const & pt = all_points_[b]; ImageType::IndexType pos; pos[0] = pt[0]; pos[1] = pt[1]; pos[2] = pt[2]; sum_interior += intensity_image->GetPixel(pos); } return sum_interior/all_points_.size(); } RegionType region = bounding_box_; if (dist_interior < 0) { //erode the mask // Generate a mask image of the cell region. Erode the region by // r_interior RegionType::SizeType size = region.GetSize(); RegionType::IndexType start={{0,0,0}}; ImageType::Pointer cropped_mask = ImageType::New(); RegionType mask_region; mask_region.SetIndex( start ); mask_region.SetSize( size ); cropped_mask->SetRegions( mask_region ); cropped_mask->Allocate(); cropped_mask->FillBuffer(0); LabelConstRegionIteratorType it1( label_image, region); RegionIteratorType it2( cropped_mask, mask_region ); for (it1.GoToBegin(), it2.GoToBegin(); !it1.IsAtEnd(); ++it1, ++it2) { if (it1.Get() == label_) it2.Set( 255 ); } ImageType::Pointer eroded_mask; ErodeFilterType::Pointer f_erode = ErodeFilterType::New(); SubFilterType::Pointer f_sub = SubFilterType::New(); StructuringElementType structuringElement; structuringElement.SetRadius( -dist_interior ); structuringElement.CreateStructuringElement(); f_erode->SetKernel( structuringElement ); f_erode->SetInput(cropped_mask); f_sub->SetInput1( cropped_mask ); f_sub->SetInput2( f_erode->GetOutput() ); try { f_sub->Update(); } catch (itk::ExceptionObject & e) { std::cerr << "Exception in SubFilter: " << e << std::endl; exit(0); } eroded_mask = f_sub->GetOutput(); // Sum the signal in the eroded region only ConstRegionIteratorType it3( eroded_mask, mask_region ); ConstRegionIteratorType it4( intensity_image, region); for (it3.GoToBegin(), it4.GoToBegin(); !it3.IsAtEnd(); ++it1, ++it3, ++it4) { if (it3.Get() > 0) { sum_interior += it4.Get(); count_interior ++; } } } if (dist_exterior > 0) { //dilate the mask // enlarge the bounding box by r on each side. RegionType::SizeType image_size = intensity_image->GetLargestPossibleRegion().GetSize(); RegionType::SizeType size = region.GetSize(); RegionType::IndexType start = region.GetIndex(); RegionType::IndexType end; end[0] = vnl_math_min(start[0]+size[0]+dist_exterior, image_size[0]); end[1] = vnl_math_min(start[1]+size[1]+dist_exterior, image_size[1]); end[2] = vnl_math_min(start[2]+size[2]+dist_exterior, image_size[2]); start[0] = vnl_math_max(int(start[0]-dist_exterior), 0); start[1] = vnl_math_max(int(start[1]-dist_exterior), 0); start[2] = vnl_math_max(int(start[2]-dist_exterior), 0); size[0] = end[0] - start[0]; size[1] = end[1] - start[1]; size[2] = end[2] - start[2]; region.SetSize( size ); region.SetIndex( start ); // Generate a mask image of the region just found. Dilate the // region defined by the segmentation by r. ImageType::Pointer cropped_mask = ImageType::New(); RegionType mask_region; start[0] = start[1] = start[2] = 0; mask_region.SetIndex( start ); mask_region.SetSize( size ); cropped_mask->SetRegions( mask_region ); cropped_mask->Allocate(); cropped_mask->FillBuffer(0); LabelConstRegionIteratorType it1( label_image, region); RegionIteratorType it2( cropped_mask, mask_region ); for (it1.GoToBegin(), it2.GoToBegin(); !it1.IsAtEnd(); ++it1, ++it2) { if (it1.Get() == label_) it2.Set( 255 ); } ImageType::Pointer dilated_mask; DilateFilterType::Pointer f_dilate = DilateFilterType::New(); SubFilterType::Pointer f_sub = SubFilterType::New(); StructuringElementType structuringElement; structuringElement.SetRadius( dist_exterior ); structuringElement.CreateStructuringElement(); f_dilate->SetKernel( structuringElement ); f_dilate->SetInput(cropped_mask); f_sub->SetInput1( f_dilate->GetOutput() ); f_sub->SetInput2( cropped_mask ); try { f_sub->Update(); } catch (itk::ExceptionObject & e) { std::cerr << "Exception in SubFilter: " << e << std::endl; exit(0); } dilated_mask = f_sub->GetOutput(); // Sum the signal in the dilated region only ConstRegionIteratorType it3( dilated_mask, mask_region ); ConstRegionIteratorType it4( intensity_image, region); for (it3.GoToBegin(), it4.GoToBegin(); !it3.IsAtEnd(); ++it1, ++it3, ++it4) { if (it3.Get() > 0) { sum_exterior += it4.Get(); count_exterior ++; } } } // average the interior and exterior signals return (sum_interior+sum_exterior)/float(count_interior+count_exterior); }
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(); */ }
void myVtkInteractorStyleImage3D::RemoveLeaks(){ boost::mutex::scoped_lock scoped_lock(_canSegment_mutex); if (!_foundLeaks){ cout << "Final segmentation had no leaks!" << endl; vtkSmartPointer<vtkNIFTIImageWriter> niw = vtkSmartPointer<vtkNIFTIImageWriter>::New(); vtkStructuredPoints* saveMat = vtkStructuredPoints::New(); cout << "At filtering." << endl; saveMat->DeepCopy(_selection); vtkUnsignedShortArray* scalars = (vtkUnsignedShortArray*)(saveMat->GetPointData()->GetScalars()); for (int i = 0; i < saveMat->GetNumberOfPoints(); i++){ if (scalars->GetValue(i) == BACKGROUND){ scalars->SetValue(i, NOT_ACTIVE); } } scalars->Modified(); //dilate: cout << "at dilation" << endl; vtkSmartPointer<vtkImageDilateErode3D> dilateErode = vtkSmartPointer<vtkImageDilateErode3D>::New(); dilateErode->SetInputData(saveMat); dilateErode->SetDilateValue(FOREGROUND); dilateErode->SetErodeValue(NOT_ACTIVE); dilateErode->SetKernelSize(DILATION_ST_SIZE, DILATION_ST_SIZE, 1); dilateErode->ReleaseDataFlagOff(); dilateErode->Update(); cout << "finished dilation" << endl; cout << "Saving..." << endl; niw->SetInputData(dilateErode->GetOutput()); niw->SetFileName("correctedImage.nii.gz"); niw->Write(); cout << "Final segmentation was saved successfully!" << endl; return; } cout << "Started fixing mesh!" << endl; typedef double PixelType; typedef unsigned short SegPixelType; const unsigned char dim = 3; typedef itk::Image<PixelType, dim> ImageType; typedef itk::Image<SegPixelType, dim> SegImageType; MeshLeaksCorrector mlc; ImageType::Pointer inputImage = mlc.read3DImage<ImageType>(_inputName.c_str()); cout << "Image reading done." << endl; typedef itk::GradientMagnitudeImageFilter<ImageType, ImageType> GradientFilterType; GradientFilterType::Pointer gradientFilter = GradientFilterType::New(); gradientFilter->SetInput(inputImage); gradientFilter->Update(); ImageType::Pointer gradientInputImage = gradientFilter->GetOutput(); cout << "Produced gradient image" << endl; typedef itk::ImageRegionIterator<ImageType> IteratorType; typedef itk::ImageRegionIterator<SegImageType> SegIteratorType; IteratorType gradIt(gradientFilter->GetOutput(), gradientFilter->GetOutput()->GetLargestPossibleRegion()); cout << "GradIt" << endl; vtkPolyDataMapper* mapper = (vtkPolyDataMapper*)(this->GetDefaultRenderer()->GetActors()->GetLastActor()->GetMapper()); vtkSmartPointer<vtkPolyData> vtkSegImage = vtkSmartPointer<vtkPolyData>::New(); vtkSegImage->DeepCopy(mapper->GetInput()); vtkSegImage->GetPointData()->SetScalars(NULL); cout << "Extracted mesh from actor" << endl; vtkSmartPointer<vtkSmoothPolyDataFilter> smoother = vtkSmoothPolyDataFilter::New(); smoother->SetInputData(vtkSegImage); smoother->SetNumberOfIterations(MESH_SMOOTH_ITERATIONS); smoother->Update(); vtkSmartPointer<vtkPolyData> mesh = smoother->GetOutput(); cout << "Mesh smoothed" << endl; typedef itk::ImageToVTKImageFilter<ImageType> ConverterType; ConverterType::Pointer gradientConverter = ConverterType::New(); gradientConverter->SetInput(inputImage); gradientConverter->Update(); vtkSmartPointer<vtkImageData> vtkGradientImage = gradientConverter->GetOutput(); cout << "Read CT image" << endl; vtkSmartPointer<vtkProbeFilter> probeFilter = vtkProbeFilter::New(); probeFilter->SetSourceData(vtkGradientImage); probeFilter->SetInputData(mesh); probeFilter->Update(); cout << "Probe finished" << endl; vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkGeometryFilter::New(); geometryFilter->SetInputData(probeFilter->GetOutput()); geometryFilter->Update(); vtkSmartPointer<vtkPolyData> gradientMesh = geometryFilter->GetOutput(); cout << "Geometric filter finished" << endl; vtkSmartPointer<vtkPolyData> minCurvatureMesh = mlc.polyDataToMinCurvature(mapper->GetInput()); cout << "mlc.minCurv finished" << endl; //just temporary - don't forget to delete vtkSmartPointer<vtkPolyData> maxCurvatureMesh = mlc.polyDataToMaxCurvature(mapper->GetInput()); // --- up to here cout << "mlc.maaxCurv finished" << endl; vtkSmartPointer<vtkPolyData> minCutMeshLeaks = mlc.minCut(minCurvatureMesh, mapper->GetInput(), gradientMesh, MIN_CURVATURE_TAG, 1.0f); cout << "minCut finished" << endl; vtkSmartPointer<vtkPolyData> minCutMeshInteriorLeaks = mlc.minCut(maxCurvatureMesh, mapper->GetInput(), gradientMesh, MAX_CURVATURE_TAG, 1.0f); cout << "minCut Interior finished" << endl; vtkSmartPointer<vtkPolyData> minCutMesh = mlc.minCutConjunction(minCutMeshLeaks, minCutMeshInteriorLeaks); cout << "Conjunction finished" << endl; mlc.attributeDilation(minCutMesh, ATTRIBUTE_DILATION_RADIUS); cout << "dilation finished" << endl; vtkSmartPointer<vtkPolyData> correctedMesh1 = mlc.laplaceInterpolation(minCutMesh); cout << "laplace finished" << endl; vtkSmartPointer<vtkPolyDataNormals> normals = vtkPolyDataNormals::New(); normals->SetInputData(correctedMesh1); normals->FlipNormalsOn(); normals->Update(); vtkSmartPointer<vtkPolyData> correctedMesh = normals->GetOutput(); cout << "Finished fixing mesh! Wow...." << endl; cout << "Writing mesh to file! laplaceMesh.vtk" << endl; mlc.writePolyData(correctedMesh, "laplaceMesh.vtk"); vtkSmartPointer<vtkDecimatePro> decimateFilter = vtkDecimatePro::New(); decimateFilter->SetInputData(correctedMesh); decimateFilter->SetTargetReduction(DECIMATION_FACTOR); decimateFilter->PreserveTopologyOn(); decimateFilter->Update(); vtkSmartPointer<vtkPolyData> decimatedMesh = decimateFilter->GetOutput(); cout << "Writing mesh to file! decimatedMesh.vtk" << endl; mlc.writePolyData(decimatedMesh, "decimatedMesh.vtk"); //2.5D NEW code //Seg input image is the selection_structured_points. (upcast to vtkImageData) typedef itk::VTKImageToImageFilter<SegImageType> SegConverterType; SegConverterType::Pointer converter = SegConverterType::New(); cout << "bedug 1" << endl; // selection is not NULL (checked...) cout << "this->_selection->GetScalarType(): " << this->_selection->GetScalarType() << endl; if (this->_selection->GetScalarType() == VTK_INT){ cout << "I have INTs instead of shorts for some reason!" << endl; } converter->SetInput(this->_selection); cout << "deb 5" << endl; converter->Update(); // cout << "bedug 2" << endl; SegImageType::Pointer segInputImage = converter->GetOutput(); cout << "bedug 3" << endl; SegImageType::Pointer outputContourImage = mlc.sampleMeshOnImage<SegImageType>(decimatedMesh, segInputImage); cout << "bedug 4" << endl; vtkSmartPointer<vtkDecimatePro> decimateFilter2 = vtkDecimatePro::New(); decimateFilter2->SetInputData(mapper->GetInput()); decimateFilter2->SetTargetReduction(DECIMATION_FACTOR); decimateFilter2->PreserveTopologyOn(); decimateFilter2->Update(); SegImageType::Pointer seedInputImage = mlc.sampleMeshOnImage<SegImageType>(decimateFilter2->GetOutput(), segInputImage); cout << "bedug 5" << endl; SegImageType::Pointer outputImage = mlc.correctImage<SegImageType>(segInputImage, seedInputImage, outputContourImage, _numTumors); //Here we should dilate: cout << "at dilation" << endl; typedef itk::BinaryBallStructuringElement<SegPixelType,3> StructuringElementType; StructuringElementType structuringElement; structuringElement.SetRadius(DILATION_ST_SIZE); structuringElement.CreateStructuringElement(); typedef itk::BinaryDilateImageFilter<SegImageType, SegImageType, StructuringElementType> BinaryDilateImageFilterType; BinaryDilateImageFilterType::Pointer dilateFilter = BinaryDilateImageFilterType::New(); dilateFilter->SetInput(outputImage); dilateFilter->SetKernel(structuringElement); dilateFilter->Update(); outputImage = dilateFilter->GetOutput(); cout << "finished dilation" << endl; //dilation end. typedef itk::ImageFileWriter<SegImageType> WriterType; WriterType::Pointer writer = WriterType::New(); cout << "bedug 6" << endl; writer->SetInput(outputImage); cout << "Writing mesh to file! correctedImage.nii.gz" << endl; writer->SetFileName("correctedImage.nii.gz"); try{ writer->Update(); } catch (itk::ExceptionObject & excp) { std::cerr << "writing input image exception thrown" << std::endl; std::cerr << excp << std::endl; exit(1); } typedef itk::ImageToVTKImageFilter<SegImageType> SegInvConverterType; SegInvConverterType::Pointer correctionConverter = SegInvConverterType::New(); cout << "bedug 7" << endl; correctionConverter->SetInput(outputImage); correctionConverter->Update(); vtkSmartPointer<vtkImageData> vtkCorrectedImage = correctionConverter->GetOutput(); vtkUnsignedShortArray* scalars = (vtkUnsignedShortArray*)(vtkCorrectedImage->GetPointData()->GetScalars()); vtkUnsignedShortArray* selection_scalars = (vtkUnsignedShortArray*)(_selection->GetPointData()->GetScalars()); for (int i = 0; i < _selection->GetNumberOfPoints(); i++){ if (scalars->GetValue(i) != NOT_ACTIVE){ //cout << scalars->GetValue(i) << endl; selection_scalars->SetValue(i, FOREGROUND); } else{ selection_scalars->SetValue(i, NOT_ACTIVE); } } selection_scalars->Modified(); this->_selection->Modified(); cout << "bedug 8" << endl; vtkSmartPointer<vtkPolyData> outputMesh = mlc.createAndSmoothSurface(vtkCorrectedImage, 50); vtkUnsignedShortArray* meshScalars = vtkUnsignedShortArray::New();// (vtkUnsignedShortArray*)(outputMesh->GetPointData()->GetScalars()); meshScalars->SetNumberOfComponents(1); meshScalars->SetNumberOfTuples(outputMesh->GetNumberOfPoints()); cout <<"outputMesh->GetNumberOfPoints()"<< outputMesh->GetNumberOfPoints() << endl; for (int i = 0; i < outputMesh->GetNumberOfPoints(); i++){ meshScalars->SetValue(i, NOT_ACTIVE); } meshScalars->SetName("mesh_colors"); meshScalars->Modified(); outputMesh->GetPointData()->RemoveArray("mesh_colors"); outputMesh->GetPointData()->SetScalars(meshScalars); outputMesh->GetPointData()->Modified(); cout << "output values: " << meshScalars->GetValue(0) << endl; mapper->GetInput()->DeepCopy(outputMesh); mapper->Modified(); cout << "We won!" << endl; }
void WholeCellSeg::BinarizationForRealBounds(){ if( !nuc_im_set || !cyt_im_set ){ std::cerr<<"Complete segmenting nuclei and set input imge before starting segmentation\n"; return; } itk::SizeValueType size1=cyt_im_inp->GetLargestPossibleRegion().GetSize()[0]; itk::SizeValueType size2=cyt_im_inp->GetLargestPossibleRegion().GetSize()[1]; if( ( size1 != nuclab_inp->GetLargestPossibleRegion().GetSize()[0] ) || ( size2 != nuclab_inp->GetLargestPossibleRegion().GetSize()[1] ) ) { std::cerr<<"The input images must be of the same size\n"; return; } typedef unsigned short int UShortPixelType; typedef itk::ImageRegionIteratorWithIndex< UShortImageType > IteratorType; typedef itk::ImageRegionConstIterator< UShortImageType > ConstIteratorType; typedef itk::Statistics::ScalarImageToHistogramGenerator< IntImageType > ScalarImageToHistogramGeneratorType; typedef ScalarImageToHistogramGeneratorType::HistogramType HistogramType; typedef itk::OtsuMultipleThresholdsCalculator< HistogramType > CalculatorType; typedef itk::RescaleIntensityImageFilter< UShortImageType, IntImageType > RescaleUsIntType; typedef itk::RescaleIntensityImageFilter< UShortImageType, UShortImageType > RescaleUsUsType; typedef itk::BinaryThresholdImageFilter< IntImageType, UShortImageType > ThreshFilterType; typedef itk::BinaryThresholdImageFilter< UShortImageType, UShortImageType > ThresholdFilterType; typedef itk::OrImageFilter< UShortImageType, UShortImageType, UShortImageType > OrFilterType; typedef itk::BinaryBallStructuringElement< UShortPixelType, 2 > StructuringElementType; typedef itk::BinaryErodeImageFilter< UShortImageType, UShortImageType, StructuringElementType > ErodeFilterType; typedef itk::BinaryDilateImageFilter< UShortImageType, UShortImageType, StructuringElementType > DilateFilterType; unsigned char *in_Image; itk::SizeValueType ind=0; //Call Yousef's binarization method if the number of bin levels is < 2 if( num_levels < 2 ){ bin_Image = (unsigned short *) malloc (size1*size2*sizeof(unsigned short)); for(itk::SizeValueType j=0; j<size2; ++j) for(itk::SizeValueType i=0; i<size1; ++i) BIN_Image(i,j)=255; in_Image = (unsigned char *) malloc (size1*size2); if( ( in_Image == NULL ) || ( bin_Image == NULL ) ){ std::cerr << "Memory allocation for binarization of image failed\n"; return; } RescaleUsUsType::Pointer rescaleususfilter = RescaleUsUsType::New(); rescaleususfilter->SetInput( cyt_im_inp ); rescaleususfilter->SetOutputMaximum( itk::NumericTraits<unsigned char>::max() ); rescaleususfilter->SetOutputMinimum( 0 ); rescaleususfilter->Update(); UShortImageType::Pointer resc_cyt_im = UShortImageType::New(); resc_cyt_im = rescaleususfilter->GetOutput(); ConstIteratorType pix_buf1( resc_cyt_im, resc_cyt_im->GetRequestedRegion() ); for ( pix_buf1.GoToBegin(); !pix_buf1.IsAtEnd(); ++pix_buf1, ++ind ) in_Image[ind]=(unsigned char)(pix_buf1.Get()); int ok = 0; ok = Cell_Binarization_2D(in_Image,bin_Image, size1, size2, shift_bin); free( in_Image ); if( !ok ){ std::cerr<<"Binarization Failed\n"; return; } //copy the output binary image into the ITK image intermediate_bin_im_out = UShortImageType::New(); UShortImageType::PointType origin; origin[0] = 0; origin[1] = 0; intermediate_bin_im_out->SetOrigin( origin ); UShortImageType::IndexType start; start[0] = 0; // first index on X start[1] = 0; // first index on Y UShortImageType::SizeType size; size[0] = size1; // size along X size[1] = size2; // size along Y UShortImageType::RegionType region; region.SetSize( size ); region.SetIndex( start ); intermediate_bin_im_out->SetRegions( region ); intermediate_bin_im_out->Allocate(); intermediate_bin_im_out->FillBuffer(0); intermediate_bin_im_out->Update(); itk::SizeValueType dum,dum1; dum = 0; dum1 = USHRT_MAX; //unsigned int asd,asd1; asd=0; asd1=0; IteratorType iterator ( intermediate_bin_im_out, intermediate_bin_im_out->GetRequestedRegion() ); for(itk::SizeValueType i=0; i < (size1*size2); ++i){ if( bin_Image[i] ) iterator.Set( dum1 ); else iterator.Set( dum ); ++iterator; } } //Call multi level binarization method if the number of bin levels is >= 2 else{ RescaleUsIntType::Pointer rescaleusintfilter = RescaleUsIntType::New(); ScalarImageToHistogramGeneratorType::Pointer scalarImageToHistogramGenerator = ScalarImageToHistogramGeneratorType::New(); rescaleusintfilter->SetInput( cyt_im_inp ); rescaleusintfilter->SetOutputMaximum( itk::NumericTraits<unsigned short>::max() ); rescaleusintfilter->SetOutputMinimum( 0 ); rescaleusintfilter->Update(); ThreshFilterType::Pointer threshfilter = ThreshFilterType::New(); CalculatorType::Pointer calculator = CalculatorType::New(); scalarImageToHistogramGenerator->SetNumberOfBins( 255 ); calculator->SetNumberOfThresholds( num_levels ); threshfilter->SetOutsideValue( (int)0 ); threshfilter->SetInsideValue( (int)USHRT_MAX ); scalarImageToHistogramGenerator->SetInput( rescaleusintfilter->GetOutput() ); scalarImageToHistogramGenerator->Compute(); calculator->SetInputHistogram( scalarImageToHistogramGenerator->GetOutput() ); threshfilter->SetInput( rescaleusintfilter->GetOutput() ); calculator->Update(); const CalculatorType::OutputType &thresholdVector = calculator->GetOutput(); CalculatorType::OutputType::const_iterator itNum = thresholdVector.begin(); int lowerThreshold,upperThreshold; for( int i=0; i<(num_levels-num_levels_incl); ++i ) ++itNum; lowerThreshold = static_cast<unsigned short>(*itNum); upperThreshold = itk::NumericTraits<unsigned short>::max(); threshfilter->SetLowerThreshold( lowerThreshold ); threshfilter->SetUpperThreshold( upperThreshold ); threshfilter->Update(); intermediate_bin_im_out = UShortImageType::New(); intermediate_bin_im_out = threshfilter->GetOutput(); } //Fill holes left by the nuclei ThresholdFilterType::Pointer binarythreshfilter = ThresholdFilterType::New(); binarythreshfilter->SetInsideValue( USHRT_MAX ); binarythreshfilter->SetOutsideValue( 0 ); binarythreshfilter->SetLowerThreshold( 1 ); binarythreshfilter->SetUpperThreshold( USHRT_MAX ); binarythreshfilter->SetInput( nuclab_inp ); OrFilterType::Pointer orfilter = OrFilterType::New(); orfilter->SetInput1( binarythreshfilter->GetOutput() ); orfilter->SetInput2( intermediate_bin_im_out ); //dialate and erode ErodeFilterType::Pointer binaryErode = ErodeFilterType::New(); DilateFilterType::Pointer binaryDilate = DilateFilterType::New(); StructuringElementType structuringElement; structuringElement.SetRadius( 3 ); // 3x3 structuring element structuringElement.CreateStructuringElement(); binaryErode->SetKernel( structuringElement ); binaryErode->SetErodeValue( USHRT_MAX ); binaryDilate->SetDilateValue( USHRT_MAX ); binaryDilate->SetKernel( structuringElement ); binaryErode->SetInput( binaryDilate->GetOutput() ); binaryDilate->SetInput( orfilter->GetOutput() ); //erode and dialate ErodeFilterType::Pointer binaryErode1 = ErodeFilterType::New(); DilateFilterType::Pointer binaryDilate1 = DilateFilterType::New(); binaryErode1->SetKernel( structuringElement ); binaryErode1->SetErodeValue( USHRT_MAX ); binaryDilate1->SetDilateValue( USHRT_MAX ); binaryDilate1->SetKernel( structuringElement ); binaryErode1->SetInput( binaryErode->GetOutput() ); binaryDilate1->SetInput( binaryErode1->GetOutput() ); binaryDilate1->Update(); //Get pointer to the final binary image and return it to calling function UShortImageType::Pointer image_bin = UShortImageType::New(); image_bin = binaryDilate1->GetOutput(); bin_im_out = image_bin; bin_done = 1; //Update bin array ind=0; if( draw_real_bounds ){ ConstIteratorType pix_buf3( bin_im_out, bin_im_out->GetRequestedRegion() ); for ( pix_buf3.GoToBegin(); !pix_buf3.IsAtEnd(); ++pix_buf3, ++ind ) bin_Image[ind]=(pix_buf3.Get()); }else free( bin_Image ); /* typedef itk::ImageFileWriter< UShortImageType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetFileName( "bin_info.tif" ); writer->SetInput( bin_im_out );//RescaleIntIO1--finalO/P writer->Update(); */ return; }
//腐蚀操作 void segmentation::erosionOperation()//未用到 { const unsigned int Dimension = 3; typedef unsigned char InputPixelType; typedef unsigned char OutputPixelType; typedef itk::Image< InputPixelType, Dimension > InputImageType; typedef itk::Image< OutputPixelType, Dimension > OutputImageType; typedef itk::ImageFileReader< InputImageType > ReaderType; typedef itk::ImageFileWriter< OutputImageType > WriterType; typedef itk::BinaryThresholdImageFilter< InputImageType, InputImageType > ThresholdFilterType; typedef itk::BinaryBallStructuringElement< InputPixelType, Dimension > StructuringElementType; typedef itk::BinaryErodeImageFilter< InputImageType, OutputImageType, StructuringElementType > ErodeFilterType; ReaderType::Pointer reader = ReaderType::New(); WriterType::Pointer writerErosion = WriterType::New(); ThresholdFilterType::Pointer thresholder = ThresholdFilterType::New(); ErodeFilterType::Pointer binaryErode = ErodeFilterType::New(); StructuringElementType structuringElementErosion; reader->SetFileName( initFileName );//读入二值图 reader->Update(); InputImageType::Pointer inputImage = InputImageType::New(); InputImageType::IndexType voxelIndex; inputImage = reader->GetOutput(); InputImageType::SizeType imgSize = inputImage->GetLargestPossibleRegion().GetSize(); long vol = 0; unsigned char temp; float r; for(int z = 0; z < imgSize[2]; z++) for(int y = 0; y < imgSize[1]; y++) for(int x = 0; x < imgSize[0]; x++) { voxelIndex[0] = x; voxelIndex[1] = y; voxelIndex[2] = z; temp = inputImage->GetPixel(voxelIndex); if(temp == 255)// 255 for PED vol += 1; } r = pow((3 * vol) / (4 * PI), (1.0 / 3)) ; r = r / 20;//experiment data structuringElementErosion.SetRadius( r ); // 3x3 structuring element structuringElementErosion.CreateStructuringElement(); binaryErode->SetKernel( structuringElementErosion ); //文件前缀名 filePrefix = inputFileName;//char* to string filePrefix = filePrefix.substr(0, filePrefix.length() - 4); string erosionFileName; erosionFileName = filePrefix + "_erosionResult.mhd"; strcpy(outputFileName, erosionFileName.c_str());//string to char* writerErosion->SetFileName(outputFileName); const InputPixelType lowerThreshold = 255; const InputPixelType upperThreshold = 255; thresholder->SetInput( reader->GetOutput() ); InputPixelType background = 0; InputPixelType foreground = 255; thresholder->SetOutsideValue( background ); thresholder->SetInsideValue( foreground ); thresholder->SetLowerThreshold( lowerThreshold ); thresholder->SetUpperThreshold( upperThreshold ); binaryErode->SetInput( thresholder->GetOutput() ); binaryErode->SetErodeValue( foreground ); writerErosion->SetInput( binaryErode->GetOutput() ); writerErosion->Update(); //binaryErode->GetOutput()->GetPixel(index);//获取像素值失败 //腐蚀结果叠加到原图 typedef itk::Image< unsigned short, Dimension > OriginalImageType; typedef itk::ImageFileReader<OriginalImageType>OriginalReaderType; OriginalReaderType::Pointer orignalImgreader = OriginalReaderType::New(); OriginalImageType::Pointer originalImage = OriginalImageType::New(); OriginalReaderType::IndexType originalImgVoxelIndex; reader->SetFileName(outputFileName);//读入腐蚀结果图像 reader->Update(); inputImage = reader->GetOutput(); orignalImgreader->SetFileName(inputFileName);//读入原图像 orignalImgreader->Update(); originalImage = orignalImgreader->GetOutput(); for(int z = 0; z < imgSize[2]; z++) for(int y = 0; y < imgSize[1]; y++) for(int x = 0; x < imgSize[0]; x++) { voxelIndex[0] = x; voxelIndex[1] = y; voxelIndex[2] = z; originalImgVoxelIndex[0] = x; originalImgVoxelIndex[1] = y; originalImgVoxelIndex[2] = z; temp = inputImage->GetPixel(voxelIndex); if(temp == 255) originalImage->SetPixel(originalImgVoxelIndex, 65535); } //输出结果 typedef itk::ImageFileWriter<OriginalImageType>NewWriterType; NewWriterType::Pointer writer = NewWriterType::New(); //文件前缀名 filePrefix = inputFileName;//char* to string filePrefix = filePrefix.substr(0, filePrefix.length() - 4); filePrefix = filePrefix + "_refinedResult.mhd"; strcpy(outputFileName, filePrefix.c_str());//string to char* writer->SetFileName(outputFileName); writer->SetInput(originalImage); writer->Update(); emit returnInternalFileName(initResultFileName);//更新原视图 emit returnOutputFileName(outputFileName);//显示结果图 }
void LidarSegmentationWidget::GenerateNeighborSinks() { Mask::Pointer sourcesImage = Mask::New(); sourcesImage->SetRegions(this->ImageRegion); ITKHelpers::IndicesToBinaryImage(this->Sources, sourcesImage); ITKHelpers::WriteImage(sourcesImage.GetPointer(), "sourcesImage.png"); // Dilate the mask std::cout << "Dilating mask..." << std::endl; typedef itk::BinaryBallStructuringElement<Mask::PixelType, 2> StructuringElementType; StructuringElementType structuringElement; structuringElement.SetRadius(1); structuringElement.CreateStructuringElement(); typedef itk::BinaryDilateImageFilter<Mask, Mask, StructuringElementType> BinaryDilateImageFilterType; BinaryDilateImageFilterType::Pointer dilateFilter = BinaryDilateImageFilterType::New(); dilateFilter->SetInput(sourcesImage); dilateFilter->SetKernel(structuringElement); dilateFilter->Update(); // Binary XOR the images to get the difference image //std::cout << "XORing masks..." << std::endl; typedef itk::XorImageFilter<Mask> XorImageFilterType; XorImageFilterType::Pointer xorFilter = XorImageFilterType::New(); xorFilter->SetInput1(dilateFilter->GetOutput()); xorFilter->SetInput2(sourcesImage); xorFilter->Update(); ITKHelpers::WriteImage(xorFilter->GetOutput(), "boundaryOfSegmentation.png"); // Iterate over the border pixels. If the closest pixel in the original segmentation has // a depth greater than a threshold, mark it as a new sink. Else, do not. std::cout << "Determining which boundary pixels should be declared background..." << std::endl; //std::cout << "There should be " << Helpers::CountNonZeroPixels(xorFilter->GetOutput()) // << " considered." << std::endl; typedef std::vector<itk::Index<2> > VectorOfPixelsType; VectorOfPixelsType newSinks; typedef itk::VectorIndexSelectionCastImageFilter<ImageType, FloatScalarImageType> IndexSelectionType; IndexSelectionType::Pointer indexSelectionFilter = IndexSelectionType::New(); indexSelectionFilter->SetIndex(3); indexSelectionFilter->SetInput(this->Image); indexSelectionFilter->Update(); FloatScalarImageType::Pointer depthImage = indexSelectionFilter->GetOutput(); //float sameObjectThreshold = 0.1f; VectorOfPixelsType consideredPixels; itk::ImageRegionIterator<Mask> imageIterator(xorFilter->GetOutput(), xorFilter->GetOutput()->GetLargestPossibleRegion()); while(!imageIterator.IsAtEnd()) { if(imageIterator.Get()) // If the current pixel is in question { consideredPixels.push_back(imageIterator.GetIndex()); } ++imageIterator; } std::cout << "There are " << consideredPixels.size() << " potential new sink pixels." << std::endl; for(VectorOfPixelsType::const_iterator iter = consideredPixels.begin(); iter != consideredPixels.end(); ++iter) { //std::cout << "Considering pixel " << consideredCounter << " (index " // << imageIterator.GetIndex() << ")" << std::endl; ImageType::PixelType currentPixel = this->Image->GetPixel(*iter); unsigned int radius = this->txtBackgroundCheckRadius->text().toUInt(); ImageType::RegionType desiredRegion = ITKHelpers::GetRegionInRadiusAroundPixel(*iter, radius); //std::cout << "desiredRegion: " << desiredRegion << std::endl; itk::ImageRegionIterator<Mask> sourcesImageIterator(sourcesImage, desiredRegion); std::vector<float> nonForegroundDepths; std::vector<float> foregroundDepths; while(!sourcesImageIterator.IsAtEnd()) { if(sourcesImageIterator.Get()) { foregroundDepths.push_back(depthImage->GetPixel(sourcesImageIterator.GetIndex())); } else { nonForegroundDepths.push_back(depthImage->GetPixel(sourcesImageIterator.GetIndex())); } ++sourcesImageIterator; } if(nonForegroundDepths.size() < 1) { } float nonForegroundMedian = Helpers::VectorMedian(nonForegroundDepths); float foregroundMedian = Helpers::VectorMedian(foregroundDepths); float difference = fabs(foregroundMedian - nonForegroundMedian); if(difference > this->txtBackgroundThreshold->text().toFloat()) { //std::cout << "Difference was " << difference << " so this is a sink pixel." << std::endl; newSinks.push_back(*iter); } else { //std::cout << "Difference was " << difference << " so this is NOT a sink pixel." << std::endl; } } // end loop over considered pixels unsigned char blue[3] = {0, 0, 255}; // ImageType::PixelType blue(3); // blue[0] = 0; // blue[1] = 0; // blue[2] = 255; ITKVTKHelpers::SetPixels(this->SourceSinkImageData.GetPointer(), consideredPixels, blue); this->SourceSinkImageData->Modified(); this->Refresh(); // Save the new sink pixels for inspection UnsignedCharScalarImageType::Pointer newSinksImage = UnsignedCharScalarImageType::New(); newSinksImage->SetRegions(this->Image->GetLargestPossibleRegion()); newSinksImage->Allocate(); ITKHelpers::IndicesToBinaryImage(newSinks, newSinksImage); ITKHelpers::WriteImage(newSinksImage.GetPointer(), "newSinks.png"); //std::cout << "Out of " << consideredCounter << " pixels considered, " // << backgroundCounter << " were declared background." << std::endl; // Set the new sinks std::cout << "Setting " << newSinks.size() << " new sinks." << std::endl; // Modify the list of sinks so it can be retrieved by the MainWindow after the segmentation is finished this->Sinks.insert(this->Sinks.end(), newSinks.begin(), newSinks.end()); UpdateSelections(); }