ITK 形态学中的开运算和闭运算 腐蚀 膨胀

一. 图像形态学处理 —— 膨胀和腐蚀

腐蚀在二值图像的基础上做“收缩”或“细化”操作;

膨胀在二值图像的基础上做“加长”或“变粗”的操作。

 

什么是二值图像呢?把一幅图片看做成一个二维的数组,那么二值图像是一个只有0和1的逻辑数组,我们前面Sobel边缘检测后的图像输出边缘效果,设置个阈值,大于阈值输出为1,小于阈值输出为0,最后输出就是一幅二值图像了。

腐蚀

腐蚀是一种消除边界点,使边界向内部收缩的过程。可以用来消除小且无意义的物体。用3X3的结构元素,扫描图像的每一个像素,用结构元素与其覆盖的二值图像做“与”操作,如果都为1,结果图像的该像素为1。否则为0。结果会使二值图像小一圈。

有一个形象的比喻来可以说明该运算,用0表示蛀虫,1表示大米。蛀虫腐蚀大米的过程便是

 

 如图所示,对于一个像素矩阵而言,只要有蛀虫(0)的存在,大米(1)就会被腐蚀掉了,即使只存在一个蛀虫(0),但是还是会被蛀虫腐蚀完毕,最后一幅图上面由于没有蛀虫(0)所以大米完好无损。

膨胀

膨胀是将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。可以用来填补物体中的空洞。用3X3的结构元素,扫描图像的每一个像素,用结构元素与其覆盖的二值图像做“与”操作,如果都为0,结果图像的该像素为0,。否则为1。结果使二值图像扩大一圈。

先腐蚀后膨胀的过程称为开运算。用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显的改变其面积。先膨胀后腐蚀的过程称为比运算,用来填充物体内细小空间、连接邻近物体、平滑其边界的同时并不明显改变其面积。

膨胀算法用最简单的比喻来描述:0表示害虫,1表示青蛙,青蛙吃了害虫表示膨胀运算,我们用3*3像素阵列来解释:

 

 

膨胀

如图所示,图左只有害虫(0),所以害虫都活着,中间那个图,虽然只有一个害虫,但是还是会被青蛙全部吃掉,最右边的那幅图,都是青蛙,所以青蛙始终是青蛙。

二. 开运算与闭运算:

    开运算:先腐蚀后膨胀,能够消除图像区域外的小白点(噪声)。

    闭运算:先膨胀后腐蚀,能够消除图像区域内的小黑点(噪声)。

 腐蚀:

//ITK
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
//#include "itkBinaryErodeImageFilter.h"//这是二值图像的腐蚀
#include "itkGrayscaleErodeImageFilter.h"
#include "itkBinaryBallStructuringElement.h"
#include "itkBinaryThresholdImageFilter.h"
//C++
#include "iostream"
using namespace std;
int main() {
    // 实例化对象模型
    const unsigned int Dimension = 2;
    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::BinaryBallStructuringElement< InputPixelType, Dimension  > StructuringElementType;
    // 腐蚀,需要用输入、输出图像类型和构造成员实例化¯
    typedef itk::GrayscaleErodeImageFilter <
    InputImageType,
    OutputImageType,
    StructuringElementType >  ErodeFilterType;
    // 读取、写入图像文件滤波器
    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName("../data/threshold.png");

    // /*创建腐蚀滤波器对象
        // 创建构造成员对象
    StructuringElementType  structuringElement;
    structuringElement.SetRadius(3);   //领域大小为3*3,结构元素se为3*3
    structuringElement.CreateStructuringElement();
    //
    ErodeFilterType::Pointer  GrayscaleErode  = ErodeFilterType::New();
    GrayscaleErode->SetInput(reader->GetOutput());
    GrayscaleErode->SetKernel(structuringElement);

    // 触发腐蚀处理后的写操作
    WriterType::Pointer writerErosion  = WriterType::New();
    writerErosion->SetFileName("../save/Erosion.png");
    writerErosion->SetInput(GrayscaleErode->GetOutput());
    writerErosion->Update();
    return EXIT_SUCCESS;
}

膨胀

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkBinaryErodeImageFilter.h"
#include "itkBinaryDilateImageFilter.h"
#include "itkBinaryBallStructuringElement.h"
#include "itkBinaryThresholdImageFilter.h"
int main() {
    // 实例化对象模型
    const unsigned int Dimension = 2;
    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;
    // 读取、写入图像文件滤波器
    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName("../data/threshold.png");

//用于二值图像的构造成员
    typedef itk::BinaryBallStructuringElement< InputPixelType, Dimension  > StructuringElementType;
    StructuringElementType  structuringElement;
    structuringElement.SetRadius(1);   //领域大小为3*3
    structuringElement.CreateStructuringElement();

    // 腐蚀,需要用输入、输出图像类型和构造成员实例化
    typedef itk::BinaryErodeImageFilter <
    InputImageType,
    OutputImageType,
    StructuringElementType >  ErodeFilterType;
    // 膨胀,需要用输入、输出图像类型和构造成员实例化
    typedef itk::BinaryDilateImageFilter <
    InputImageType,
    OutputImageType,
    StructuringElementType >  DilateFilterType;

    // 创建腐蚀和膨胀滤波器对象
    ErodeFilterType::Pointer  binaryErode  = ErodeFilterType::New();
    binaryErode->SetInput(reader->GetOutput());
    binaryErode->SetKernel(structuringElement);
    binaryErode->SetErodeValue(255);
    binaryErode->Update();
    //
    DilateFilterType::Pointer binaryDilate = DilateFilterType::New();
    binaryDilate->SetInput(reader->GetOutput());
    binaryDilate->SetKernel(structuringElement);
    binaryDilate->SetDilateValue(255);
    binaryDilate->Update();
    typedef itk::ImageFileWriter< OutputImageType >  WriterType;
    WriterType::Pointer writerErosion  = WriterType::New();
    writerErosion->SetFileName("../save/1Erosion.png");
    writerErosion->SetInput(binaryErode->GetOutput());
    writerErosion->Update();
    WriterType::Pointer writerDilation = WriterType::New();
    writerDilation->SetFileName("../save/1Dilation.png");
    writerDilation->SetInput(binaryDilate->GetOutput());
    writerDilation->Update();
    
    return EXIT_SUCCESS;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恋恋西风

up up up

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值