OTSU 分割(最大类间方差阈值分割)
实例19 OTSU算法对PNG图像进行单阈值二维分割
#include "itkOtsuThresholdImageFilter.h"//Otsu分割头文件
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
int main( int argc, char * argv[] )
{
/*if( argc < 5 )
{
std::cerr << "Usage: " << argv[0];
std::cerr << " inputImageFile outputImageFile ";
std::cerr << " insideValue outsideValue " << std::endl;
return EXIT_FAILURE;
}*/
//确定作为输入和输出图像的像素类型
typedef unsigned char InputPixelType;
typedef unsigned char OutputPixelType;
const unsigned int Dimension = 2;
//使用输入输出图像的像素类型和维来定义它们的图像类型
typedef itk::Image< InputPixelType, Dimension > InputImageType;
typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
//使用上面定义的输入输出图像的类型对滤波器类型进行实例化
typedef itk::OtsuThresholdImageFilter<InputImageType, OutputImageType > FilterType;
//对一个 itk::ImageFileReader 类也进行实例化以便从文件中读取图像数据
typedef itk::ImageFileReader< InputImageType > ReaderType;
typedef itk::ImageFileWriter< OutputImageType > WriterType;
//调用 New( ) 方式创建滤波器和 reader 并将结果指向 itk::Smartpointers
ReaderType::Pointer reader = ReaderType::New();
FilterType::Pointer filter = FilterType::New();
WriterType::Pointer writer = WriterType::New();
//由 reader 得到的图像作为输入传递给 OtsuThresholdImageFilter
reader->SetFileName("BrainProtonDensitySlice.png");
filter->SetInput(reader->GetOutput());
writer->SetInput( filter->GetOutput() );
//outsideValue:给定阈值的上下限范围之外的像素的亮度值
//insideValue:给定阈值的上下限范围之内的像素的亮度值
const OutputPixelType outsideValue = atoi( "0" );//范围之外设置为纯黑
const OutputPixelType insideValue = atoi( "255" );//范围之内设置为纯白
/*用 SetOutsideValue() 方式定义指向那些亮度值在给定阈值的上下限范围之外的像素的
亮度值,用 SetInsideValue() 方式定义指向那些亮度值在给定阈值的上下限范围之内的像素的
亮度值*/
filter->SetOutsideValue( outsideValue );
filter->SetInsideValue( insideValue );
try
{
filter->Update();
}
catch( itk::ExceptionObject & excp )
{
std::cerr << "Exception thrown " << excp << std::endl;
}
//由滤波器内部计算得到的阈值。为了做到这些我们调用 GetThreshold 方式
int threshold = filter->GetThreshold();
std::cout << "Threshold = " << threshold << std::endl;
writer->SetFileName( "BrainProtonDensitySlice_OTSU2.png" );
try
{
writer->Update();
}
catch( itk::ExceptionObject & excp )
{
std::cerr << "Exception thrown " << excp << std::endl;
}
return EXIT_SUCCESS;
}
得到分割阈值为98:
当给定阈值的上下限范围之内、之外的像素的亮度值分别给定为255(纯白显示)、0(纯黑显示)时:
输入图像 OTSU分割图
当给定阈值的上下限范围之内、之外的像素的亮度值分别给定为0(纯黑显示)、255(纯白显示)时:
输入图像 OTSU分割图
另外一个对像素进行分类的方法就是把错分类率降到最小。这样就要寻找一个阈值,这个阈值将图像分为两部分,并且使得其中一部分落在另一部分那侧的直方图降到最小。这等同于将类中的差异最小化或者说将类之间的差异最大化。这个图展示了这种滤波器在进行分割时的自身局限性,这些局限性在处理含噪声的图像和由于领域偏见而缺乏空间均匀性的MRI图像时表现得尤为突出。
ITK系列目录:
注:例程配套素材见系列目录