1、GrayscaleFillholeImageFilter 填充孔洞,不对边缘造成影响(无平滑边缘效果)
itk提供了两个的补洞类:itkGrayscaleFillholeImageFilter(针对灰度图像), itkBinaryFillholeImageFilter(针对二值图像)
//孔洞填充(灰度图像)
typedef itk::GrayscaleFillholeImageFilter
FillHoleType::Pointer fillHoleFilter = FillHoleType::New();
fillHoleFilter->SetInput(thresholder1->GetOutput());
fillHoleFilter->Update();
2、洞穴充填滤波器 填充孔洞+平滑边缘
Voting 滤波器的另一个变量是 Hold Filling 滤波器。这个滤波器仅仅在前景像素的数量在邻域中占大多数时将背景像素转变为前景。通过选择大多数的尺度,这个滤波器可以填充135 不同尺度的洞。为了更加精确,这个滤波器的效果和当前像素的边缘曲率密切相关。 本小节的源代码在文件 Examples/Filtering/VotingBinaryHoleFillingImageFilter.cxx 中。itk::VotingBinaryHoleFillingImageFilter 应用一个 Voting 操作以便于填充洞穴。这也可以用来在二值图像中平滑轮廓和填充洞穴。
//首先必须包含与这个滤波器相关的头文件:
#include "itkVotingBinaryHoleFillingImageFilter.h"
//然后必须定义输入和输出图像的像素和图像类型:
typedef unsigned char InputPixelType;
typedef unsigned char OutputPixelType;
typedef itk::Image< InputPixelType, 2 > InputImageType;
typedef itk::Image< OutputPixelType, 2 > OutputImageType;
//现在可以使用图像类型来定义滤波器的类型并创建滤波器对象:
typedef itk::VotingBinaryHoleFillingImageFilter<
InputImageType, OutputImageType > FilterType;
FilterType::Pointer filter = FilterType::New( );
//通过对相应的值传递一个 SizeType 对象来定义沿每个维的邻域大小。每个维的值作为一个矩形框的不完全尺寸来使用。例如:在二维情况下一个大小为 1×2 的 SizeType 将产生一个 3×5 的邻域。
InputImageType::SizeType indexRadius;// 生成一个领域
indexRadius[0] = radiusX; // 输入x方向领域半径
indexRadius[1] = radiusY; // 输入y方向领域半径
filter->SetRadius( indexRadius );// 导入一个领域
//由于这个滤波器需要一个二值图像作为输入,所以我们必须指定用来作为背景和前景的
灰度级。可以通过使用 SetForegroundValue( )和 SetBackgroundValue( )方式来设置:
filter->SetBackgroundValue( 0 );//背景像素值
filter->SetForegroundValue( 255 );//前景像素值
//我们也必须指定用来作为判别将背景像素转变为前景像素的判断标准的大多数阈值。
//转变的规则是:通过这个大多数阈值来判断,如果邻域中前景的数量大于背景的数量,就将背景像素转变为前景像素。
//例如:在一个二维图像中,选择邻域半径为 1,则邻域大小为 3×3。如果我们设置大多数阈值为 2,则我们需要邻域中前景的数量至少为(3×3-1)/2 并加上大多数值。这可以使用 SetMajorityThreshold( )方式来完成:
filter->SetMajorityThreshold( 2 );//比平均领域数量多一个"大多数值"
filter->SetInput( reader->GetOutput( ) );
writer->SetInput( filter->GetOutput( ) );
writer->Update( );
3、例子
//孔洞填充
//008
//reader-intensityWindowing-thresholder-(StructuringElement)-Dilate-Erode-writer
#include "itkImageFileReader.h"//读取头文件
#include "itkImageFileWriter.h"//写入头文件
#include "itkGDCMImageIO.h"//ImageIo头文件
#include "itkIntensityWindowingImageFilter.h"//调窗处理头文件
#include "itkBinaryThresholdImageFilter.h"//二值门限处理头文件
#include "itkBinaryBallStructuringElement.h"//基本球形
#include "itkBinaryErodeImageFilter.h"
#include "itkBinaryDilateImageFilter.h"
#include "itkGrayscaleFillholeImageFilter.h"//灰度图像孔洞填充
int main(int argc, char* argv[])
{
typedef signed short PixelType; // signed short 数据类型
typedef itk::Image< PixelType, 2 > ImageType;//image类型
typedef itk::ImageFileReader< ImageType > ReaderType;
typedef itk::ImageFileWriter< ImageType > WriterType;
ReaderType::Pointer reader = ReaderType::New();//reader
WriterType::Pointer writer = WriterType::New();//writer
typedef itk::GDCMImageIO ImageIOType;
ImageIOType::Pointer gdcmImageIO = ImageIOType::New();//gdcmImageIO
reader->SetFileName("D:/leg_dcm/IM70.dcm");//读取文件
reader->SetImageIO(gdcmImageIO);
reader->Update();
//调窗处理
typedef itk::IntensityWindowingImageFilter
IntensityFilterType::Pointer intensityWindowing = IntensityFilterType::New();
intensityWindowing->SetWindowMinimum(124);//最小窗值
intensityWindowing->SetWindowMaximum(126);//最大窗值
intensityWindowing->SetOutputMinimum(0);//
intensityWindowing->SetOutputMaximum(255); //
intensityWindowing->SetInput(reader->GetOutput());//
intensityWindowing->Update();
//二值门限
typedef itk::BinaryThresholdImageFilter
ThresholdingFilterType::Pointer thresholder = ThresholdingFilterType::New();
thresholder->SetInput(intensityWindowing->GetOutput());
thresholder->SetUpperThreshold(255);//上下阈值参数设定
thresholder->SetLowerThreshold(250);
thresholder->SetOutsideValue(0);//输出值设定,背景为0,前景为255
thresholder->SetInsideValue(255);
thresholder->Update();
//用于二值图像的构造成员
typedef itk::BinaryBallStructuringElement< PixelType, 2 > StructuringElementType;
StructuringElementType structuringElement;
structuringElement.SetRadius(1); //领域大小为3*3
structuringElement.CreateStructuringElement();
//开运算:先膨胀再腐蚀
typedef itk::BinaryErodeImageFilter
typedef itk::BinaryDilateImageFilter
DilateFilterType::Pointer binaryDilate = DilateFilterType::New();
binaryDilate->SetInput(thresholder->GetOutput());
binaryDilate->SetKernel(structuringElement);
binaryDilate->SetDilateValue(255);
binaryDilate->Update();
ErodeFilterType::Pointer binaryErode = ErodeFilterType::New();
binaryErode->SetInput(binaryDilate->GetOutput());
binaryErode->SetKernel(structuringElement);
binaryErode->SetErodeValue(255);
binaryErode->Update();
//闭运算:先腐蚀再膨胀
ErodeFilterType::Pointer binaryErode1 = ErodeFilterType::New();
binaryErode1->SetInput(binaryErode->GetOutput());
binaryErode1->SetKernel(structuringElement);
binaryErode1->SetErodeValue(255);
binaryErode1->Update();
DilateFilterType::Pointer binaryDilate1 = DilateFilterType::New();
binaryDilate1->SetInput(binaryErode1->GetOutput());
binaryDilate1->SetKernel(structuringElement);
binaryDilate1->SetDilateValue(255);
binaryDilate1->Update();
//二值门限处理
typedef itk::BinaryThresholdImageFilter
ThresholdingFilterType::Pointer thresholder1 = ThresholdingFilterType::New();
thresholder1->SetInput(binaryDilate1->GetOutput());
thresholder1->SetUpperThreshold(255);//上下阈值参数设定
thresholder1->SetLowerThreshold(250);
thresholder1->SetOutsideValue(0);//输出值设定,背景为0,前景为255
thresholder1->SetInsideValue(255);
thresholder1->Update();
//孔洞填充(灰度图像)
typedef itk::GrayscaleFillholeImageFilter
FillHoleType::Pointer fillHoleFilter = FillHoleType::New();
fillHoleFilter->SetInput(thresholder1->GetOutput());
fillHoleFilter->Update();
writer->SetInput(fillHoleFilter->GetOutput());
writer->SetFileName("D:/008.dcm");
writer->SetImageIO(gdcmImageIO);
writer->Update();
return EXIT_SUCCESS;
}
参考:[itk孔洞填充](https://blog.csdn.net/weixin_43798712/article/details/122777331)