一. 图像形态学处理 —— 膨胀和腐蚀
图解图像腐蚀和膨胀
二. 开运算与闭运算:
开运算:先腐蚀后膨胀,能够消除图像区域外的小白点(噪声)。
闭运算:先膨胀后腐蚀,能够消除图像区域内的小黑点(噪声)。
图解图像开运算与闭运算
为什么有了膨胀、腐蚀还要开运算闭运算呢?其实开闭运算最重要的一点就是,可以保持物体原有大小。然后一个是消除物体外部噪声(开运算)的另一个是增强物体之间连接点(闭运算)的。
数学形态学操作通过对每个输入像素的邻域应用一个操作来实现。规则和邻域的结合被称为构造成员。尽管一些规则已经成为图像处理的实际标准,但是使用什么类型的算法规则应用于邻域还是有很大的选择自由的。
在 ITK 中是在最小化腐蚀和最大化膨胀的典型规则下实现的。构造成员是作为一个 NeighborhoodOperator 来实现的。事实上,默认的构造成员是itk::BinaryBallStructuringElement 类。这个类是使用像素类型和输入图像维来进行实例化的。
构造成员不是一个引用记数类。因此它是作为一个 C++ 堆栈而不是使用 New( ) 和 SmartPointers 来创建的。使用 SetRadius( ) 方式来定义和构造成员相关的邻域半径并调用CreateStructuringElement( )方式以便于初始化操作符。如下面所阐述的那样,使用 SetKernel( )方式将构造成员的结果传递给数学形态学滤波器。
#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"
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<ImageType, ImageType > IntensityFilterType;
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<ImageType, ImageType > ThresholdingFilterType;
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 <ImageType, ImageType, StructuringElementType > ErodeFilterType;// 腐蚀,需要用输入、输出图像类型和构造成员实例化
typedef itk::BinaryDilateImageFilter <ImageType, ImageType, StructuringElementType > DilateFilterType;// 膨胀,需要用输入、输出图像类型和构造成员实例化
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();
//开运算(腐蚀)后二值门限处理
typedef itk::BinaryThresholdImageFilter<ImageType, ImageType > ThresholdingFilterType;
ThresholdingFilterType::Pointer thresholder1 = ThresholdingFilterType::New();
thresholder1->SetInput(binaryErode->GetOutput());
thresholder1->SetUpperThreshold(255);//上下阈值参数设定
thresholder1->SetLowerThreshold(250);
thresholder1->SetOutsideValue(0);//输出值设定,背景为0,前景为255
thresholder1->SetInsideValue(255);
thresholder1->Update();
writer->SetInput(thresholder1->GetOutput());
writer->SetFileName("D:/004.dcm");
writer->SetImageIO(gdcmImageIO);
writer->Update();
return EXIT_SUCCESS;
}