Canny边缘检测
在VTK中没有实现一个专门的类来做Canny边缘检测。
通过以下步骤实现:
1)对源图像进行高斯平滑以消除图像中噪声
2)采用差分法近似计算图像每一个像素的梯度,并计算梯度的模值和方向
3)对梯度进行"非极大抑制":图像边缘点梯度值通常在梯度方向是极大值,因此检测边缘需要将非极大值赋值0来抑制非边缘点。
检测方法就是在一个局部窗口内,如果中心像素点的梯度不比梯度方向上相邻两个像素值大,那么该中心像素点梯度值赋0。
4)双阈值法检测边缘和连接边缘。取两个梯度阈值high和low,将梯度图像中小于high的像素赋0得到边缘图像I1,
该图像能够接近图像边缘但是可能会存在间断点;将梯度图像中小于low的像素赋0得到边缘图像I2,该图中受噪声影响比较大,但是边缘信息更多。
在连接边缘时,以I1为基础,对非零点进行边缘跟踪,如果追踪过程中出现中断,则从I2对应像素点及其邻域来寻找可以连接的边缘,直至结束。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import vtk
reader = vtk.vtkJPEGReader() # 读入灰度图
reader.SetFileName(r'E:/lena-gray.jpg')
reader.Update()
ic = vtk.vtkImageCast()
ic.SetOutputScalarTypeToFloat()
ic.SetInputConnection(reader.GetOutputPort())
ic.Update()
gs = vtk.vtkImageGaussianSmooth()
gs.SetInputConnection(ic.GetOutputPort())
gs.SetDimensionality(2)
gs.SetRadiusFactors(1, 1, 0)
gs.Update()
imgGradient = vtk.vtkImageGradient()
imgGradient.SetInputConnection(gs.GetOutputPort())
imgGradient.SetDimensionality(2)
imgGradient.Update()
imgMagnitude = vtk.vtkImageMagnitude()
imgMagnitude.SetInputConnection(imgGradient.GetOutputPort())
imgMagnitude.Update()
nonMax = vtk.vtkImageNonMaximumSuppression()
'''
vtkImageNonMaximumSuppression 该类将图像中的非局部峰值设置为0,其输入和输出的类型都是imageData
输入两个为模值图像和矢量图像,一个典型的应用就是输入梯度模值图像和梯度向量图像对梯度做非极大值抑制。
'''
nonMax.SetMagnitudeInputData(imgMagnitude.GetOutput())
nonMax.SetVectorInputData(imgGradient.GetOutput())
nonMax.SetDimensionality(2)
nonMax.Update()
pad = vtk.vtkImageConstantPad()
'''
vtkImageConstantPad 用于增加图像的大小,其输入和输出都是imagedata类型
SetOutputNumberOfScalarComponents()用于设置输出图像的