方法介绍
ITK 中边缘检测方法用到的是 Canny Edge Delection,用于图像中各结构轮廓的提取。
为了取得一个不错的结果,Canny 边缘检测内置封装多中算法,涉及到的算法有用
-
利用高斯模糊来如初图像中的噪点;
-
通过计算像素递归梯度来定位边缘调整;
-
非最大抑去除 suprious 特征;
-
设置阈值最终得到二值化图像;
虽然整个边缘检测的的数据管道流对于用户来说相对比较抽象,但是对这些组分的充分理解,可以调节到比较合适的参数,得到不错的结果
代码实现
实现时用到 itk::CannyEdgeDetectionImageFilter 头文件;在下面这个例子中因为读取是 PNG 格式图片,因此图像读取时用到的数据类型为 unsigned char;
但是 CannyEdgeDetectionImageFilter 处理的图像格式需是 double ,因此在 Filter 处理之前,用 CastImageFilter 把 unsigned char 格式转化为 double;
最后文件写出之前利用 RescaleIntensityImageFilter 将 double 转化为 unsigned char,写出 PNG 图像;
边缘检测时,需要设置三个参数值 ;
-
SetVariance() ,设置一个值用于图像高斯模糊;
-
SetUpperThreshold() ,设置一个选择阈值的最大临界点;
-
SetLowerThreshold() , 设置阈值范围的最低临界点;
#include<itkImageFileReader.h>
#include<itkImageFileWriter.h>
#include<itkCastImageFilter.h>
#include<itkRescaleIntensityImageFilter.h>
#include<itkCannyEdgeDetectionImageFilter.h>
#include<itkPNGImageIOFactory.h>
using namespace std;
int main()
{
itk::PNGImageIOFactory::RegisterOneFactory();
using CharPixelType = unsigned char;
using RealPixelType = double;
string input_name = "D:/ceshi1/ITK/Filter/Edge_Detection/input.png";
string output_name = "D:/ceshi1/ITK/Filter/Edge_Detection/output.png";
using CharImageType = itk::Image<CharPixelType, 2>;
using RealImageType = itk::Image<RealPixelType, 2>;
using ReaderType = itk::ImageFileReader<CharImageType>;
using WriterType = itk::ImageFileWriter<CharImageType>;
using CastToRealFilterType = itk::CastImageFilter<CharImageType, RealImageType>;
using CannyFilterType = itk::CannyEdgeDetectionImageFilter<RealImageType, RealImageType>;
using RescaleFilterType = itk::RescaleIntensityImageFilter<RealImageType, CharImageType>;//Real to Char
ReaderType::Pointer reader = ReaderType::New();
CastToRealFilterType::Pointer toReal = CastToRealFilterType::New();
CannyFilterType::Pointer cannyFilter = CannyFilterType::New();
RescaleFilterType::Pointer rescale = RescaleFilterType::New();
WriterType::Pointer writer = WriterType::New();
reader->SetFileName(input_name);
writer->SetFileName(output_name);
toReal->SetInput(reader->GetOutput());//Cast unsigned char to double;
cannyFilter->SetInput(toReal->GetOutput());//Get double;
rescale->SetInput(cannyFilter->GetOutput());//reacale;
writer->SetInput(rescale->GetOutput());
cannyFilter->SetVariance(5.0);
cannyFilter->SetUpperThreshold(1.0);
cannyFilter->SetLowerThreshold(1.0);
try
{
writer->Update();
}
catch (const itk::ExceptionObject &e)
{
cout << "Exceptation Caught" << std::endl;
cout << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
代码中,处理的图像为 ITK 官网 提供的大脑切片 PNG 格式,Variance 设置为 5.0,UpperThreshold 和 LowerThreshold 都设置为 1.0;最终的呈现效果如下
Snipaste_2020-05-03_21-17-44.png
网友评论