? ? ? ??
在生长区域中包含像素的一个简单标准是以一个特殊的间距来计算亮度值。
????????本小节的源代码在文件 Examples/Segmentation/ConnectedThresholdImageFilter.cxx
中。
????????接下来的例子阐述了 itk:: ConnectedThresholdImageFilter 的用法。这个滤波器使用注水迭代器。区域生长方法最主要的算法复杂性是访问相邻像素。注水迭代器承担起这个责任并大大简化了区域生长算法的执行。剩下的算法就是确定一个是否应该将一个特殊的像素包含到当前区域中的标准。 ConnectedThresholdImageFilter 使用的标准是基于用户提供的一个亮度值间距,需要提供上下限的值。区域生长算法包括那些亮度在标准中的像素。
????????I(X) ∈
[lower,upper]?
????????现在我们来看一下使用这个算法需要的最简单的代码。
????????首先,必须包含含有ConnectedThresholdImageFilter 类的头文件:#include "itkConnectedThresholdImageFilter.h" ???????
? ? ? ??图像中存在的噪声将大大降低滤波器生长大面积区域的能力。当面对噪声图像时,通常是使用一个边缘保留平滑滤波器。(平滑滤波器需要浮点型数据)
//在这个特定例子里我们使用 itk:: ConnectedThresholdImageFilter,我们需要包含它的头文件:
#include "itkCurvatureFlowImageFilter.h"
//我们基于一个特殊的像素类型和维来定义图像类型。由于平滑滤波器的需要,在这里我们使用浮点型数据定义像素:
typedef float InternalPixelType;
const unsigned int Dimension = 2;
typedef itk::Image< InternalPixelType, Dimension > InternalImageType;
//使用图像类型作为模板参数来对平滑滤波器进行实例化:
typedef itk::CurvatureFlowImageFilter< InternalImageType, InternalImageType >
CurvatureFlowImageFilterType;
//然后调用 New( )方式来创建滤波器并将接指向 itk::SmartPointer:
CurvatureFlowImageFilterType::Pointer smoothing =
CurvatureFlowImageFilterType::New( );
//现在我们声明区域生长滤波器的类型,本例中使用 ConnectedThresholdImageFilter:
typedef itk::ConnectedThresholdImageFilter< InternalImageType,
InternalImageType > ConnectedFilterType;
//然后我们使用 New( )方式构造这种类的一个滤波器:
ConnectedFilterType::Pointer connectedThreshold = ConnectedFilterType::New( );
//现在到了连接一个简单的线性管道的时候。在管道的开头添加一个 reader 件头并在末尾添加一个 cast filter 和 writer。由于只有一小部分图像文件格式支持浮点型数据类型,所以使用 cast filter 将浮点型数据类型转换成整型。
smoothing->SetInput( reader->GetOutput( ) );
connectedThreshold->SetInput( smoothing->GetOutput( ) );
caster->SetInput( connectedThreshold->GetOutput( ) );
writer->SetInput( caster->GetOutput( ) );
//CurvatureFlowImageFilter 需要定义两个参数。下面是一个二维图像的常见值。当然它们也需要根据输入图像存在的噪声的数量进行适当的调整。
smoothing->SetNumberOfIterations( 5 );
smoothing->SetTimeStep( 0.125 );
//ConnectedThresholdImageFilter 有两个主要的参数需要定义,它们分别是为了确定是否包含在区域中的亮度值而制定的标准的上门限和下门限。这两个值设定得太接近势必会降低区域生长的机动性,而设定得太远必将整个图像都卷入区域中。
connectedThreshold->SetLower( lowerThreshold );
connectedThreshold->SetUpper( upperThreshold );
//这个滤波器的输出是一个二值图像,这个二值图像除了分割出的区域外到处都是零值像素。区域中的亮度值是由 SetReplaceValue( )方式来选择的:
connectedThreshold->SetReplaceValue( 255 );
//这个算法的实例化需要用户提供一个种子点。将这个点选在被分割的解剖学结构的典型区域是很便捷的。种子是以一种itk::Index的形式传递给SetSeed( )方式的:
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;
}
????????区域分割的另外一个选择是利用由 ConnectedThresholdImageFilter
在处理多种子时提供的优点。使用 AddSeed( )
方式可以将一个接一个的传递给滤波器。你可以想象一个用户界面,在这个界面中被分割对象的多个点是都有一个操作键并且没个选择点作为一个种子传递给这个滤波器。
|