Сегментация изображения не выполняется, если метод setpixel не был вызван на входном изображении - PullRequest
1 голос
/ 18 апреля 2019

Я пытаюсь реализовать алгоритм сегментации изображений itk. Похоже, что это работает, когда входные изображения построены с помощью метода setpixel. Когда я строю входное изображение, используя технику itk пространственного объекта, сегментация не работает, пока я не вызову setpixel для произвольного индекса входного изображения со значением. Когда я даже вызываю setpixel (index, 0), который не меняет значение пикселя, ничего не происходит. Похоже, мне нужно перевернуть значение буфера. Ввод создан правильно, потому что я могу визуализировать его. Я также проверяю происхождение, расстояние, направление, размер и все выглядит правильно.

// Сделать входное изображение:
typedef itk :: EllipseSpatialObject <3> EllipseType; typedef itk :: SpatialObjectToImageFilter SpatialObjectToImageFilterType; SpatialObjectToImageFilterType :: Pointer imageFilter = SpatialObjectToImageFilterType :: New ();

Mask3DImageType::SizeType size {{100,100,100}};
imageFilter->SetSize(size);

Mask3DImageType::SpacingType spacing;
spacing[0] =1;
spacing[1] =1;
spacing[2] =1;
imageFilter->SetSpacing(spacing);

EllipseType::Pointer ellipse =EllipseType::New();
ellipse->SetRadiusInObjectSpace(50);

EllipseType::PointType center;
center[0] =50;
center[1] =50;
center[2] =50;
ellipse->SetCenterInObjectSpace(center);

// Position the ellipse
typedef EllipseType::TransformType TransformType;
TransformType::Pointer transform = TransformType::New();
transform->SetIdentity();
imageFilter->SetInput(ellipse);
ellipse->SetObjectToParentTransform(transform);

ellipse->SetDefaultInsideValue(255);
ellipse->SetDefaultOutsideValue(0);
ellipse->SetRequestedRegionToLargestPossibleRegion();
imageFilter->SetUseObjectValue( true );

// make the data direction:
Mask3DImageType::DirectionType imageDirectionType;
for(int iRow=0; iRow<3; ++iRow){
    for(int iCol=0; iCol<3; ++iCol)
        imageDirectionType(iRow,iCol) = 0;
}
imageDirectionType(0,0) = 1;
imageDirectionType(1,1) = 1;
imageDirectionType(2,2) = 1;
imageFilter->SetDirection(imageDirectionType);

Mask3DImageType::PointType inputOrigin;
inputOrigin[0] =0;
inputOrigin[1] =0;
inputOrigin[2] =0;
imageFilter->SetOrigin(inputOrigin);
imageFilter->Update();
inputMaskImage = imageFilter->GetOutput();
inputMaskImage->DisconnectPipeline();

// the next few lines are required for the segmentation algorithm to work:
Mask3DImageType::IndexType pixelIndex;
pixelIndex[0] = 0;
pixelIndex[1] = 0;
pixelIndex[2] = 0;
inputMaskImage->SetPixel(pixelIndex, 255 /*does not work if 0 because it does not change the pixel value*/);

///////// Алгоритм сегментации ////////////////

assert(inputMaskImage);
using ApproximateSignedDistanceMapImageFilterType = itk::ApproximateSignedDistanceMapImageFilter<Mask3DImageType,Real3DImageType>;
using ContourExtractor2DImageFilterType =itk::ContourExtractor2DImageFilter<Real2DImageType>;
using ExtractFilterType =itk::ExtractImageFilter<Real3DImageType,Real2DImageType>;

using InvertIntensityImageFilterType =itk::InvertIntensityImageFilter <Mask3DImageType>;

InvertIntensityImageFilterType::Pointer invertIntensityFilter = InvertIntensityImageFilterType::New();
invertIntensityFilter->SetInput(inputMaskImage);
invertIntensityFilter->SetMaximum(iContourValue);
try{

    invertIntensityFilter->Update();
}
catch( itk::ExceptionObject & error ){

    return false;
}

ApproximateSignedDistanceMapImageFilterType::Pointer approximateSignedDistanceMapImageFilter = ApproximateSignedDistanceMapImageFilterType::New();
approximateSignedDistanceMapImageFilter->SetNumberOfWorkUnits(iCpuCoreCount);
approximateSignedDistanceMapImageFilter->SetInput(invertIntensityFilter->GetOutput());
approximateSignedDistanceMapImageFilter->SetInsideValue(0);
approximateSignedDistanceMapImageFilter->SetOutsideValue(iContourValue);
try{

    approximateSignedDistanceMapImageFilter->Update();
}
catch( itk::ExceptionObject & error ){

    return false;
}
Real3DImageType::Pointer inputMappedImage = approximateSignedDistanceMapImageFilter->GetOutput();
inputMappedImage->DisconnectPipeline();

Real3DImageType::RegionType inputRegion =inputMappedImage->GetLargestPossibleRegion();
Real3DImageType::SizeType inputSize =inputRegion.GetSize();
Real3DImageType::SpacingType inputSpacingType =inputMappedImage->GetSpacing();
Real3DImageType::PointType inputOriginType =inputMappedImage->GetOrigin();

// ii)
ContourExtractor2DImageFilterType::Pointer contourExtractor2DImageFilter =ContourExtractor2DImageFilterType::New();
contourExtractor2DImageFilter->SetNumberOfWorkUnits(iCpuCoreCount);

ExtractFilterType::Pointer extractFilterType = ExtractFilterType::New();
extractFilterType->SetNumberOfWorkUnits(iCpuCoreCount);

for(int iDir=0; iDir<3; ++iDir){

    if( !isReplaceAxialContours &&  AxialViewer==iDir )
        break;

    Real3DImageType::RegionType outputRegion =inputRegion;
    Real3DImageType::SizeType outputSize =outputRegion.GetSize();
    Real3DImageType::IndexType outputIndex =outputRegion.GetIndex();
    outputSize[iDir] =0;

    for (auto iSlice = roiSliceSequence[iDir].begin(); iSlice != roiSliceSequence[iDir].end(); /*No Incerement*/){
        iSlice = roiSliceSequence[iDir].erase(iSlice);
    }

    for(int iSlice=0; iSlice<inputSize[iDir]; ++iSlice){

        // extract slice:
        outputIndex[iDir] = iSlice;
        extractFilterType->SetInput(inputMappedImage);
        extractFilterType->SetExtractionRegion(Real3DImageType::RegionType(outputIndex,outputSize));
        extractFilterType->SetDirectionCollapseToSubmatrix();
        try{

            extractFilterType->Update();
        }
        catch(itk::ExceptionObject & error){

            return false;
        }
        Real2DImageType::Pointer sliceImage = extractFilterType->GetOutput();
        sliceImage->DisconnectPipeline();

        // get contour:
        contourExtractor2DImageFilter->SetInput(sliceImage);
        contourExtractor2DImageFilter->SetContourValue(0);
        try{

            contourExtractor2DImageFilter->Update();
        }
        catch(itk::ExceptionObject & error){

            return false;
        }

        ROI::Slice<float> *roiSlice = new ROI::Slice<float>();
        roiSlice->iCoord = iSlice;
        roiSlice->fCoord = inputOriginType[iDir]+iSlice*inputSpacingType[iDir];

        for(unsigned int iContour =0; iContour<contourExtractor2DImageFilter->GetNumberOfOutputs(); ++iContour){

            roiSlice->contourPointDeque.push_back(std::deque<std::array<float,2>>());
            ContourExtractor2DImageFilterType::VertexListType::ConstIterator vertexItr = contourExtractor2DImageFilter->GetOutput(iContour)->GetVertexList()->Begin();
            while(vertexItr != contourExtractor2DImageFilter->GetOutput(iContour)->GetVertexList()->End()){

                roiSlice->contourPointDeque.back().push_back({(float)vertexItr->Value()[0],(float)vertexItr->Value()[1]});
                ++vertexItr;
            }
        }

        roiSliceSequence[iDir].push_back(roiSlice);
    }
}
...