ITK系列17_ 区域增长(连接门限)对脑部切片PNG图像进行二维分割

40 篇文章 2 订阅
34 篇文章 29 订阅

区域生长

区域生长算法被证实是一个有效的图像分割方法。区域生长的基本方法是从被分割对象里作为种子区域 ( 通常是一个或多个像素 ) 的一个区域开始,在种子区域的相邻像素寻找与种子像素有相同或相似性质的像素,并将这些像素合并到种子像素所在的区域中。将这些新像素当作新的种子区域继续进行上述过程。区域生长算法主要取决于用来选择确定为种子区域像素的标准、用来确定相邻像素的连通性类型和用来访问相邻像素的策略。

连接门限

在生长区域中包含像素的一个简单标准是以一个特殊的间距来计算亮度值。

接下来的例子阐述了 itk:: ConnectedThresholdImageFilter 的用法。这个滤波器使用注水迭代器。区域生长方法最主要的算法复杂性是访问相邻像素注水迭代器承担起这个责任并大大简化了区域生长算法的执行。剩下的算法就是确定一个是否应该将一个特殊的像素包含到当前区域中的标准。ConnectedThresholdImageFilter 使用的标准是基于用户提供的一个亮度值间距,需要提供上下限的值。区域生长算法将包括那些亮度在亮度值间距标准中的像素
                                                                                       I(X)  ∈ [lower,upper] 

实例17 连接门限对脑部切片PNG图像进行二维分割

#include "itkConnectedThresholdImageFilter.h"//连接门限头文件
#include "itkImage.h"
#include "itkCastImageFilter.h"
#include "itkCurvatureFlowImageFilter.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
//图像中存在的噪声将大大降低滤波器生长大面积区域的能力。当面对噪声图像时,通常
//是使用一个边缘保留平滑滤波器。
int main( int argc, char *argv[])
{
  /*if( argc < 7 )
    {
    std::cerr << "Missing Parameters " << std::endl;
    std::cerr << "Usage: " << argv[0];
    std::cerr << " inputImage  outputImage seedX seedY lowerThreshold upperThreshold" << std::endl;
    return EXIT_FAILURE;
    }*/
  /*我们基于一个特殊的像素类型和维来定义图像类型。由于平滑滤波器的需要,在这里我
  们使用浮点型数据定义像素*/
  typedef   float           InternalPixelType;
  const     unsigned int    Dimension = 2;
  typedef itk::Image< InternalPixelType, Dimension >  InternalImageType;

  typedef unsigned char                            OutputPixelType;
  typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
  typedef itk::CastImageFilter< InternalImageType, OutputImageType >
                                                   CastingFilterType;
  CastingFilterType::Pointer caster = CastingFilterType::New();

  //图像读取与图像写类型定义
  typedef  itk::ImageFileReader< InternalImageType > ReaderType;
  typedef  itk::ImageFileWriter<  OutputImageType  > WriterType;
  //图像读取与图像写对象实例化
  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName( "BrainProtonDensitySlice.png" );
  writer->SetFileName( "BrainProtonDensitySlice_huizhi.png" );

  //使用图像类型作为模板参数来对平滑滤波器进行实例化
  typedef itk::CurvatureFlowImageFilter< InternalImageType, InternalImageType >
  CurvatureFlowImageFilterType;
  //调用 New() 方式来创建滤波器并将接指向 itk::SmartPointer
  //平滑滤波器实例化对象smoothing
  CurvatureFlowImageFilterType::Pointer smoothing =
                         CurvatureFlowImageFilterType::New();
  //声明区域生长滤波器的类型,本例中使用 ConnectedThresholdImageFilter
  typedef itk::ConnectedThresholdImageFilter< InternalImageType,
                                    InternalImageType > ConnectedFilterType;
  //使用 New( ) 方式构造这种类的一个滤波器
  //连接门限滤波器实例化对象connectedThreshold
  ConnectedFilterType::Pointer connectedThreshold = ConnectedFilterType::New();
  //读取图像进行平滑滤波
  smoothing->SetInput( reader->GetOutput() );
  //滤波后进行连接门限
  connectedThreshold->SetInput( smoothing->GetOutput() );
  /*由于只有一小部分图像文件格式支持浮点型数据类型,所以使
  用 cast filter 将浮点型数据类型转换成整型*/
  caster->SetInput( connectedThreshold->GetOutput() );
  //处理后输出数据到writer
  writer->SetInput( caster->GetOutput() );
  /*CurvatureFlowImageFilter(平滑滤波器)需要定义两个参数。下面是一个二维图像的常见值。
  当然它们也需要根据输入图像存在的噪声的数量进行适当的调整*/
  smoothing->SetNumberOfIterations( 5 );
  smoothing->SetTimeStep( 0.125 );
  /*ConnectedThresholdImageFilter(连通门限图像滤波)有两个主要的
  参数(lowerThreshold和upperThreshold)需要定义,
  它们分别是为了确定是否包含在区域中的亮度值而制定的标准的上门限和下门限。
  这两个值设定得太接近势必会降低区域生长的机动性,而设定得太远必将整个图像都卷入区域中*/
  const InternalPixelType lowerThreshold = atof( "180" );
  const InternalPixelType upperThreshold = atof( "210" );

  connectedThreshold->SetLower(  lowerThreshold  );
  connectedThreshold->SetUpper(  upperThreshold  );
  /*这个滤波器的输出是一个二值图像,这个二值图像除了分割出的区域外到处都是零值像
  素。区域中的亮度值是由 SetReplaceValue() 方式来选择的*/
  connectedThreshold->SetReplaceValue( 255 );
  
  InternalImageType::IndexType  index;

  /*这个算法的实例化需要用户提供一个种子点index。将这个点选在被分割的解剖学结构的典型
 区域是很便捷的。种子是以一种 itk::Index 的形式传递给 SetSeed() 方式的*/
  index[0] = atoi( "107" );
  index[1] = atoi( "69" );
  connectedThreshold->SetSeed( index );
  /*writer 上的 Updata() 方法引发了管道的运行。通常在出现错误和抛出异议时, 从一个
  try / catch 模块调用 updata :*/
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;
    }
    return EXIT_SUCCESS;
}

脑部组织结构图像进行分割时可参考的参数:

                                         

                                 

               输入图像                                 分割出的白质组织                    分割出的脑室组织                     分割出的灰质组织

注意:灰质部分并没有被完全分割,这就是区域生长方法在对被分割的解剖学结构在图像空间上没有相似的统计分布时进行分割的弱点。你可以通过使用不同的上下限值进行分割,以达到扩展可接受区域的目的
区域分割的另外一个选择是利用由 ConnectedThresholdImageFilter 在处理多种子时提供的优点。使用 AddSeed( ) 方式可以将一个接一个的传递给滤波器。你可以想象一个用户界面,在这个界面中被分割对象的多个点是都有一个操作键并且没个选择点作为一个种子传递给这个滤波器。

 

ITK系列目录:

1 ITK图像数据表达之图像

2 ITK图像处理之图像滤波

3 ITK图像处理之图像分割

注:例程配套素材见系列目录

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用SimpleITK进行二维区域生长图像分割,可以按照以下步骤进行操作: 1. 导入SimpleITK库和其他必要的库: ```python import SimpleITK as sitk import numpy as np import matplotlib.pyplot as plt ``` 2. 读取需要分割图像: ```python image = sitk.ReadImage('your_image_path') ``` 3. 定义种子点,即生长的起点: ```python seed = (x, y) # 替换为实际需要的种子点的坐标 ``` 4. 定义生长的条件: ```python lower_threshold = 0 # 最小像素值 upper_threshold = 200 # 最大像素值 neighborhood_radius = 1 # 邻域半径 ``` 5. 调用SimpleITK区域生长函数: ```python seg = sitk.Image(image.GetSize(), sitk.sitkUInt8) seg.CopyInformation(image) seg[np.where(np.asarray(sitk.GetArrayFromImage(image)) < lower_threshold)] = 0 seg[np.where(np.asarray(sitk.GetArrayFromImage(image)) > upper_threshold)] = 0 seg = sitk.BinaryDilate(seg, neighborhood_radius) seg = sitk.BinaryErode(seg, neighborhood_radius) seg = sitk.ConnectedThreshold(image1=image, seedList=[seed], lower=lower_threshold, upper=upper_threshold, replaceValue=1) ``` 6. 可选:将分割结果转换为numpy数组并进行可视化: ```python seg_np = sitk.GetArrayFromImage(seg) plt.imshow(seg_np, cmap='gray') plt.show() ``` 在上面的代码中,您需要将“your_image_path”替换为实际图像的路径,并根据需要修改种子点和生长条件的值。这些参数控制了生长的起点和条件,以及分割结果的形态。 此外,SimpleITK还提供了其他区域生长函数,如ConfidenceConnected和NeighborhoodConnected等。您可以根据自己的需要和偏好选择其中的一个函数来实现分割

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

亦我飞也

你的鼓励将是我创作的最大动力!

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

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

打赏作者

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

抵扣说明:

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

余额充值