分享

ITK-膨胀

 翟天保的图书馆 2024-11-02 发布于上海

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

膨胀原理

       ‌‌图像形态学膨胀是图像处理中的一种基本操作,主要用于特征增强、去噪、分割和边缘检测等。其基本原理是通过使用一个称为结构元素的模板对图像进行局部区域的最大值操作。膨胀操作通过将结构元素在图像上滑动,当结构元素与目标区域有交集时,将中心像素设置为前景,从而实现目标区域的扩张‌。

       OpenCV膨胀示例参考:

       OpenCV-膨胀cv::dilate-CSDN博客

       本文介绍如何用ITK实现图像形态学膨胀。

环境准备

参见:Windows下用CMake编译ITK及配置测试_itk配置-CSDN博客

功能解析

1.引入必要的头文件:

#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkBinaryDilateImageFilter.h>
#include <itkFlatStructuringElement.h>
#include <itkJPEGImageIOFactory.h>
#include <itkBinaryThresholdImageFilter.h>

2.初始化图像类型和读写器:

// 定义图像类型
typedef itk::Image<unsigned char, 2> CharImageType;
typedef itk::ImageFileReader<CharImageType> ReaderType;
typedef itk::ImageFileWriter<CharImageType> WriterType;
// 注册JPEG格式支持
itk::JPEGImageIOFactory::RegisterOneFactory();
// 定义结构元素类型
typedef itk::FlatStructuringElement<2> StructuringElementType;
// 创建读取器和写入器
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
WriterType::Pointer binaryWriter = WriterType::New(); // 用于保存二值化图像

3.设置文件名:

// 设置要读取和写入的文件
reader->SetFileName("test.jpg");
writer->SetFileName("dilated_image.jpg");
binaryWriter->SetFileName("binary_image.jpg"); // 二值化图像的输出文件名

4.创建二值化滤波器:

// 创建二值化滤波器
typedef itk::BinaryThresholdImageFilter<CharImageType, CharImageType> ThresholdFilterType;
ThresholdFilterType::Pointer thresholdFilter = ThresholdFilterType::New();
thresholdFilter->SetInput(reader->GetOutput());
thresholdFilter->SetLowerThreshold(128);  // 适当设置阈值
thresholdFilter->SetUpperThreshold(255);
thresholdFilter->SetInsideValue(255);    // 前景值
thresholdFilter->SetOutsideValue(0);     // 背景值

5.创建膨胀滤波器:

// 创建结构元素,使用合适的半径类型
StructuringElementType::RadiusType radius;
radius.Fill(1); 
// 创建正方形结构元素
StructuringElementType structuringElement = StructuringElementType::Box(radius);
// 创建膨胀滤波器
typedef itk::BinaryDilateImageFilter<CharImageType, CharImageType, StructuringElementType> DilateFilterType;
DilateFilterType::Pointer dilateFilter = DilateFilterType::New();
dilateFilter->SetInput(thresholdFilter->GetOutput());
dilateFilter->SetKernel(structuringElement);

6.连接过滤器输出到写入器并执行写入操作:

// 将膨胀图像作为输出图像
writer->SetInput(dilateFilter->GetOutput());
// 执行更新
try
{
    // 首先保存二值化图像
    binaryWriter->Update();
    // 然后保存膨胀图像
    writer->Update();
}
catch (itk::ExceptionObject& error)
{
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
}

完整代码

#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkBinaryDilateImageFilter.h>
#include <itkFlatStructuringElement.h>
#include <itkJPEGImageIOFactory.h>
#include <itkBinaryThresholdImageFilter.h>

int main()
{
    // 定义图像类型
    typedef itk::Image<unsigned char, 2> CharImageType;
    typedef itk::ImageFileReader<CharImageType> ReaderType;
    typedef itk::ImageFileWriter<CharImageType> WriterType;

    // 注册JPEG格式支持
    itk::JPEGImageIOFactory::RegisterOneFactory();

    // 定义结构元素类型
    typedef itk::FlatStructuringElement<2> StructuringElementType;

    // 创建读取器和写入器
    ReaderType::Pointer reader = ReaderType::New();
    WriterType::Pointer writer = WriterType::New();
    WriterType::Pointer binaryWriter = WriterType::New(); // 用于保存二值化图像

    // 设置要读取和写入的文件
    reader->SetFileName("test.jpg");
    writer->SetFileName("dilated_image.jpg");
    binaryWriter->SetFileName("binary_image.jpg"); // 二值化图像的输出文件名

    // 创建二值化滤波器
    typedef itk::BinaryThresholdImageFilter<CharImageType, CharImageType> ThresholdFilterType;
    ThresholdFilterType::Pointer thresholdFilter = ThresholdFilterType::New();
    thresholdFilter->SetInput(reader->GetOutput());
    thresholdFilter->SetLowerThreshold(128);  // 适当设置阈值
    thresholdFilter->SetUpperThreshold(255);
    thresholdFilter->SetInsideValue(255);    // 前景值
    thresholdFilter->SetOutsideValue(0);     // 背景值

    // 保存二值化图像
    binaryWriter->SetInput(thresholdFilter->GetOutput());

    // 创建结构元素,使用合适的半径类型
    StructuringElementType::RadiusType radius;
    radius.Fill(1); 

    // 创建正方形结构元素
    StructuringElementType structuringElement = StructuringElementType::Box(radius);

    // 创建膨胀滤波器
    typedef itk::BinaryDilateImageFilter<CharImageType, CharImageType, StructuringElementType> DilateFilterType;
    DilateFilterType::Pointer dilateFilter = DilateFilterType::New();
    dilateFilter->SetInput(thresholdFilter->GetOutput());
    dilateFilter->SetKernel(structuringElement);

    // 将膨胀图像作为输出图像
    writer->SetInput(dilateFilter->GetOutput());

    // 执行更新
    try
    {
        // 首先保存二值化图像
        binaryWriter->Update();

        // 然后保存膨胀图像
        writer->Update();
    }
    catch (itk::ExceptionObject& error)
    {
        std::cerr << "Error: " << error << std::endl;
        return EXIT_FAILURE;
    }

    std::cout << "Dilation completed successfully." << std::endl;
    return EXIT_SUCCESS;
}

测试效果 

​原图:

​​​​​​​​二值图及膨胀效果:

       注意结构元素Fill(1),指3*3的窗口,半径为1。

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多