ITK canny边缘检测

来源:互联网 发布:电信宽带网络测速 编辑:程序博客网 时间:2024/06/06 06:44
canny边缘检查原理:

经典的Canny边缘检测算法通常都是从高斯模糊开始,到基于双阈值实现边缘连接结束。但是在实际工程应用中,考虑到输入图像都是彩色图像,最终边缘连接之后的图像要二值化输出显示,所以完整的Canny边缘检测算法实现步骤下:

1.      彩色图像转换为灰度图像

2.      对图像进行高斯模糊

3.      计算图像梯度,根据梯度计算图像边缘幅值与角度

4.      非最大信号压制处理(边缘细化)

5.      双阈值边缘连接处理

6.      二值化图像输出结果

ITK 关于Canny边缘检测的示例代码在InsightToolkit4.11.0\Examples\Segmentation\CannySegmentationLevelSetImageFilter

代码如下:


#include "itkImage.h"
#include "itkCannySegmentationLevelSetImageFilter.h"
#include "itkGradientAnisotropicDiffusionImageFilter.h"//关于图像梯度计算
#include "itkFastMarchingImageFilter.h"//快速图像匹配
#include "itkBinaryThresholdImageFilter.h"//图像二值化
#include "itkImageFileReader.h"//读入
#include "itkImageFileWriter.h"//写出
#include "itkZeroCrossingImageFilter.h"//过0点检测

int main( int argc, char *argv[] )
{
  if( argc < 9 )//参数个数检查
    {
    std::cerr << "Missing Parameters " << std::endl;
    std::cerr << "Usage: " << argv[0];
    std::cerr << " InputImage  InitialModel OutputImage";
    std::cerr << " CannyThreshold ";
    std::cerr << " CannyVariance ";
    std::cerr << " AdvectionWeight";
    std::cerr << " InitialModelIsovalue";
    std::cerr << " MaximumIterations";
    std::cerr << " [OutputSpeedImage]" << 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::BinaryThresholdImageFilter<
                        InternalImageType,
                        OutputImageType    >       ThresholdingFilterType;

//上下阈值参数设定
  ThresholdingFilterType::Pointer thresholder = ThresholdingFilterType::New();
  thresholder->SetUpperThreshold( 10.0 );
  thresholder->SetLowerThreshold( 0.0 );

//输出值设定,背景为0,前景为255
  thresholder->SetOutsideValue(  0  );
  thresholder->SetInsideValue(  255 );

//图像读写
  typedef  itk::ImageFileReader< InternalImageType > ReaderType;
  typedef  itk::ImageFileWriter<  OutputImageType  > WriterType;


  ReaderType::Pointer reader1 = ReaderType::New();
  ReaderType::Pointer reader2 = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();


  reader1->SetFileName( argv[1] );
  reader2->SetFileName( argv[2] );
  writer->SetFileName(  argv[3] );
//梯度计算
  typedef itk::GradientAnisotropicDiffusionImageFilter< InternalImageType,
    InternalImageType> DiffusionFilterType;
  DiffusionFilterType::Pointer diffusion = DiffusionFilterType::New();
  diffusion->SetNumberOfIterations(5);
  diffusion->SetTimeStep(0.125);
  diffusion->SetConductanceParameter(1.0);
  // Software Guide : EndCodeSnippet


//canny边缘检测
  typedef  itk::CannySegmentationLevelSetImageFilter< InternalImageType,
                InternalImageType > CannySegmentationLevelSetImageFilterType;
  CannySegmentationLevelSetImageFilterType::Pointer cannySegmentation =
                CannySegmentationLevelSetImageFilterType::New();

//参数传入
  cannySegmentation->SetAdvectionScaling( ::atof(argv[6]) );
  cannySegmentation->SetCurvatureScaling( 1.0 );
  cannySegmentation->SetPropagationScaling( 0.0 );
  cannySegmentation->SetThreshold( ::atof(argv[4]) );
  cannySegmentation->SetVariance(  ::atof(argv[5]) );
  cannySegmentation->SetIsoSurfaceValue( ::atof(argv[7]) );
  diffusion->SetInput( reader1->GetOutput() );
  cannySegmentation->SetInput( reader2->GetOutput() );
  cannySegmentation->SetFeatureImage( diffusion->GetOutput() );
  thresholder->SetInput( cannySegmentation->GetOutput() );
  writer->SetInput( thresholder->GetOutput() );
 

  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;
    return EXIT_FAILURE;
    }
 
  std::cout << std::endl;
  std::cout << "Max. no. iterations: " << cannySegmentation->GetNumberOfIterations() << std::endl;
  std::cout << "Max. RMS error: " << cannySegmentation->GetMaximumRMSError() << std::endl;
  std::cout << std::endl;
  std::cout << "No. elpased iterations: " << cannySegmentation->GetElapsedIterations() << std::endl;
  std::cout << "RMS change: " << cannySegmentation->GetRMSChange() << std::endl;



  if( argc > 9 )
    {
    const char * speedImageFileName = argv[9];

    cannySegmentation->GenerateSpeedImage();
    typedef CannySegmentationLevelSetImageFilterType::SpeedImageType
                                                             SpeedImageType;
    typedef itk::ImageFileWriter<SpeedImageType>             SpeedWriterType;
    SpeedWriterType::Pointer speedWriter = SpeedWriterType::New();
    speedWriter->SetInput( cannySegmentation->GetSpeedImage() );
    speedWriter->SetFileName( speedImageFileName );


    try
      {
      speedWriter->Update();
      }
    catch( itk::ExceptionObject & excep )
      {
      std::cerr << "Exception caught ! while writing the speed image" << std::endl;
      std::cerr << "Filename : " << speedImageFileName << std::endl;
      std::cerr << excep << std::endl;
      return EXIT_FAILURE;
      }
    }


  return EXIT_SUCCESS;
}

0 0