【ITK库学习】使用itk库进行图像分割(三):分水岭分割算法

目录

  • [1、 itkWaterShedImageFilter 分水岭滤波器](#1、 itkWaterShedImageFilter 分水岭滤波器)
  • [2、itkMorphologicalWatershedImageFilter 形态学分水岭滤波器](#2、itkMorphologicalWatershedImageFilter 形态学分水岭滤波器)
  • [3、itkIsolatedWatershedImageFilter 岛屿分水岭滤波器](#3、itkIsolatedWatershedImageFilter 岛屿分水岭滤波器)

1、 itkWaterShedImageFilter 分水岭滤波器

分水岭分割对图像特征基于梯度下降法和沿区域边界分析弱点将像素进行分类。

该类可从标量值图像输入自动生成分段、标记图像的层次结构。

概述和术语

该过滤器实现了图像分割算法的非流版本,通常称为"分水岭分割"。 分水岭分割因其算法将区域分割为流域盆地的方式而得名。 如果函数 f 是在图像域上定义的连续高度函数,则集水盆地定义为其最陡下降路径终止于 f 的相同局部最小值的点集。

高度函数(输入)的选择取决于应用,并且基本分水岭算法的运行独立于该选择。 对于基于强度的图像数据,通常可以使用某种梯度幅度计算作为输入。

分水岭算法步骤:

首先,通过沿着每个点的最陡下降路径追踪到局部最小值,将所有点初步分类为集水盆地区域;

然后,根据某些显着性度量(例如最小边界高度)分析相邻区域及其之间的边界,以生成相邻区域之间的合并树, 这些合并发生在不同的最大显着性值处,达到指定显着性"洪水级别"的所有可能合并的集合在本文档中被称为"合并树"。

打个比方,洪水位是反映流入集水盆地的降水量的值。 随着洪水水位上升,相邻路段之间的边界被侵蚀,这些路段合并, 洪水级别的最小值为零,最大值为输入图像中最高值和最低值之间的差。

请注意,一旦完成初始分析和分割以生成合并树,在恒定时间内生成标记图像的层次结构就很简单了,该算法的复杂性在于合并树的计算,创建该树后,可以通过简单地从树中识别分段合并的子集来重新标记初始分段图像,以反映在树中找到的任何最大显着性值。

实施细节

该过滤器是几个较低级别流程对象(名称空间"watershed"中的分水岭算法组件)的包装器,组件类被设计为在数据流或非数据流模式下运行,在此类的GenerateData()方法中构造的管道不支持流式传输。

输入

该过滤器的输入是任意维度的标量itk::Image,假设该输入图像表示某种基于要分割的原始图像的高度函数或边缘图(例如由 itk::GradientMagnitudeImageFilter 生成的图像),除了阈值步骤之外,该过滤器不会对其输入进行任何预处理,该算法没有明确要求输入为任何特定数据类型,但建议使用浮点或双精度数据。

建议对输入到该算法的标量图像进行预处理是使用 itk::AnisotropicDiffusionImageFilter 子类之一来平滑原始图像,然后基于梯度或曲率执行某种边缘计算。

输出

该过滤器将生成 IdentifierType 整数类型且与输入图像具有相同维度的 itk::ImageIdentifierType 输出图像在本文档中称为"标记图像",图像中的每个像素都分配有一个IdentifierType 整数标签,将其分组在连接区域内。

注意事项

有两个参数控制该滤波器的输出:阈值Threshold 和水平Level ,两个参数的单位都是输入中最大高度值的百分比。

**Threshold **用于设置处理过程中使用的绝对最小高度值,,假设阈值去除的浅层区域不太重要,提高这个阈值百分比可以有效地减少输入中局部最小值的数量,从而产生具有更少区域的初始分割。
Level 参数控制图像隐喻泛滥的深度,也就是说,它设置了结果中感兴趣的最大显着性值,升高和降低级别会影响基本分段中合并以产生最终输出的分段数量,级别 1.0 类似于将图像淹没到图像中最大值的 100% 的深度, 0.0 级别产生基本分割,通常会过度分割,感兴趣的级别值通常较低(即小于约 0.40 或 40%),因为较高的值很快就会开始对图像进行欠分割。

初始分割完成后,Level 参数可用于在恒定时间内创建输出图像的层次结构,典型场景可能如下所示:对于过滤器的初始执行,将级别设置为预计可能感兴趣的最大显着性值,一旦该过程对象的初始 Update()完成,就可以在低于初始设置的任何位置操作 Level,而不会触发分段微型管道的完整更新,现在生成新输出所需要做的就是对输出图像进行简单的重新标记。
ThresholdLevel 参数通过类的 Get/SetThreshold()Get/SetLevel() 方法进行控制。

常用的成员函数

  • SetInput():设置输入图像
  • Set/GetThreshold():设置/获取输入阈值参数,单位是图像中最大深度的百分比
  • Set/GetLevel():设置/获取从初始分段生成合并树的洪水级别
  • GetSegmentTree():从 TreeGenerator 成员过滤器获取分割树
  • GetBasicSegmentation():从Segmenter成员过滤器中获取基本分段

示例代码

cpp 复制代码
#include "itkImage.h"
#include "itkWaterShedImageFilter.h"

typedef itk::Image<float, 3> FloatImageType;

bool watershedImageFilter(FloatImageType* image, double threshold, double level)
{
    typedef itk::WatershedImageFilter<FloatImageType> WatershedFilterType;
	typename WatershedFilterType::Pointer watershedFilter = WatershedFilterType::New();
	watershedFilter->SetInput(image);
	//Level 控制分水岭深度;Threshold控制输入的下阈值
	//两个参数均设置为输入图像中最大深度的百分比 (0.0 - 1.0)
	watershedFilter->SetThreshold(threshold);
	watershedFilter->SetLevel(level);
	try
	{
		watershedFilter->Update();
	}
	catch (itk::ExceptionObject& ex)
	{
		//读取过程发生错误
		std::cerr << "Error: " << ex << std::endl;
		return false;
	}
	return true;
}

2、itkMorphologicalWatershedImageFilter 形态学分水岭滤波器

该类使用形态学算子实现分水岭分割。

分水岭像素标记为 0,TOutputImage 应该是整数类型,输出图像的标签没有特定的顺序。 可以通过将此过滤器的输出传递给 RelabelComponentImageFilter来重新排序标签,使对象标签连续并根据对象大小进行排序。

常用的成员函数

  • Set/GetFullyConnected():设置/获取连通分量是严格通过面连通性还是通过面+边+顶点连通性定义, 默认为完全连接关闭,对于1像素宽的对象,请使用 ExcellentConnectedOn,函数FullyConnectedOn/Off()功能相同
  • Set/GetLevel():设置/获取分水岭深度级别
  • Set/GetMarkWatershedLine():设置/获取是否必须标记分水岭像素,默认为 true,设置为 false 不仅可以避免写入分水岭像素,还可以降低算法复杂度
cpp 复制代码
#include "itkImage.h"
#include "itkMorphologicalWatershedImageFilter.h"

typedef itk::Image<float, 3> FloatImageType;
typedef itk::Image<short, 3> ShortImageType;

bool morphologicalWatershedImageFilter(FloatImageType* image, ShortImageType* outImage, double level)
{
    typedef itk::MorphologicalWatershedImageFilter<FloatImageType, ShortImageType> MorphWatershedFilterType;
	typename MorphWatershedFilterType::Pointer watershedFilter = MorphWatershedFilterType::New();
	watershedFilter->SetInput(image);
	watershedFilter->SetLevel(level);
	//watershedFilter->SetFullyConnected(true);
	try
	{
		watershedFilter->Update();
	}
	catch (itk::ExceptionObject& ex)
	{
		//读取过程发生错误
		std::cerr << "Error: " << ex << std::endl;
		return false;
	}
	outImage = watershedFilter->GetOutput();
	return true;
}

3、itkIsolatedWatershedImageFilter 岛屿分水岭滤波器

该类使用两个种子点隔离流域盆地。

IndependentWatershedImageFilter 使用 ReplaceValue1 标记与 Seed1 位于同一流域盆地且与 Seed2 不同的像素,滤波器调节水位,直到两个种子在不同的盆中, 用户可以置分水岭阈值,该算法使用二分搜索来调整上水位,从 UpperValueLimit开始。

常用的成员函数

  • Set/GetSeed1():设置/获取种子点 1,该种子将与 Seed2 隔离(如果可能),连接到该种子的所有像素都将替换为ReplaceValue1
  • Set/GetSeed2():设置/获取种子点 2,该种子将与 Seed1 隔离(如果可能),连接到该种子的所有像素都将替换为 ReplaceValue2
  • Set/GetReplaceValue1/2():设置/获取替换Seed1/Seed2连通区域的像素值,即包含 Seed1/Seed2盆地内的像素值, 默认ReplaceValue1值为 1,ReplaceValue2值为0
  • Set/GetThreshold():设置/获取分水岭阈值, 默认值为 0
  • Set/GetUpperValueLimit():设置/获取水位上限值,默认值为 1.0
  • Set/GetIsolatedValueTolerance():设置/获取强度阈值所需的精度,默认值为 0.001
  • GetIsolatedValue():获取隔离两个种子的值
cpp 复制代码
#include "itkImage.h"
#include "itkIsolatedWatershedImageFilter.h"

typedef itk::Image<float, 3> FloatImageType;
typedef itk::Image<short, 3> ShortImageType;

bool isolatedWatershedImageFilter(FloatImageType* image, ShortImageType* outImage)
{
	FloatImageType::IndexType seed1 = { 5,5,5 };
	FloatImageType::IndexType seed2 = { 10,10,10 };
	short replaceValue1 = 255;
	short replaceValue2 = 0;
	double threshold = 0.0;

    typedef itk::IsolatedWatershedImageFilter<FloatImageType, ShortImageType> IsolatedWatershedFilterType;
	typename IsolatedWatershedFilterType::Pointer isolateWaterShedFilter = IsolatedWatershedFilterType::New();
	isolateWaterShedFilter->SetInput(image);
	isolateWaterShedFilter->SetSeed1(seed1);
	isolateWaterShedFilter->SetSeed2(seed2);
	isolateWaterShedFilter->SetReplaceValue1(replaceValue1);   //替换seed1的连通区域值,即包含seed1盆地内的像素值
	isolateWaterShedFilter->SetReplaceValue2(replaceValue2);   //替换seed2的连通区域值,即包含seed2盆地内的像素值
	isolateWaterShedFilter->SetThreshold(threshold);           //设置分水岭阈值
	try
	{
		isolateWaterShedFilter->Update();
	}
	catch (itk::ExceptionObject& ex)
	{
		//读取过程发生错误
		std::cerr << "Error: " << ex << std::endl;
		return false;
	}
	outImage = isolateWaterShedFilter->GetOutput();
	return true;
}
相关推荐
cuisidong19972 分钟前
5G学习笔记三之物理层、数据链路层、RRC层协议
笔记·学习·5g
小刘|7 分钟前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
南宫理的日知录10 分钟前
99、Python并发编程:多线程的问题、临界资源以及同步机制
开发语言·python·学习·编程学习
jjyangyou12 分钟前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计
van叶~29 分钟前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法
简简单单做算法30 分钟前
基于Retinex算法的图像去雾matlab仿真
算法·matlab·图像去雾·retinex
knighthood200139 分钟前
解决:ros进行gazebo仿真,rviz没有显示传感器数据
c++·ubuntu·ros
云卓SKYDROID44 分钟前
除草机器人算法以及技术详解!
算法·机器人·科普·高科技·云卓科技·算法技术
数据与后端架构提升之路1 小时前
从神经元到神经网络:深度学习的进化之旅
人工智能·神经网络·学习
半盏茶香1 小时前
【C语言】分支和循环详解(下)猜数字游戏
c语言·开发语言·c++·算法·游戏