05-VTK在图像处理中的应用(8)

5.13 图像平滑

图像平滑常用于图像的预处理中,如计算梯度时先对图像进行平滑处理,可以减少噪声对梯度的影响。图像平滑一般是通过模板卷积运算实现。模板可以看做是一个大小为nxn的小图像,例如3×3,5×5等等,模板的每个像素都对应一个系数值。模板卷积运算的过程是首先将模板中心依次与图像每个像素重合,通过模板各个系数与图像对应像素相乘来计算模板对应像素的加权平均值,最后将运算结果赋给图像中模板中心对应的像素。

5.13.1 均值滤波

均值滤波是一种经常用到的平滑方法,其对应的模板各个像素的值为1。在VTK中没有直接实现均值滤波的类,但是我们可以通过图像卷积运算来实现。卷积运算通过vtkImageConvolve类实现。通过vtkImageConvolve类,只需要设置相应的卷积模板,便可以实现多种空域图像滤波。下面代码说明了怎样使用vtkImageConvolve类来实现图像的均值滤波。

 

1:      vtkSmartPointer<vtkJPEGReader>reader =

  2:         vtkSmartPointer<vtkJPEGReader>::New();

  3:     reader->SetFileName("lena2.jpg");

  4:      reader->Update();

  5:  

  6:     vtkSmartPointer<vtkImageCast> originalCastFilter =

  7:         vtkSmartPointer<vtkImageCast>::New();

  8:     originalCastFilter->SetInputConnection(reader->GetOutputPort());

  9:     originalCastFilter->SetOutputScalarTypeToFloat();

 10:     originalCastFilter->Update();

 11:  

 12:     vtkSmartPointer<vtkImageConvolve> convolveFilter =

 13:          vtkSmartPointer<vtkImageConvolve>::New();

 14:     convolveFilter->SetInputConnection(originalCastFilter->GetOutputPort());

 15:      double kernel[25] ={0.04,0.04,0.04,0.04,0.04,

 16:                      0.04,0.04,0.04,0.04,0.04,

 17:                       0.04,0.04,0.04,0.04,0.04,

 18:                      0.04,0.04,0.04,0.04,0.04,

 19:                      0.04,0.04,0.04,0.04,0.04};

 20:     convolveFilter->SetKernel5x5(kernel);

 21:     convolveFilter->Update();

 22:  

 23:      vtkSmartPointer<vtkImageCast>convCastFilter =

 24:         vtkSmartPointer<vtkImageCast>::New();

 25:     convCastFilter->SetInput(convolveFilter->GetOutput());

 26:     convCastFilter->SetOutputScalarTypeToUnsignedChar();

 27:      convCastFilter->Update();

 

首先vtkJPEGReader对象读取一幅图像。考虑到进行卷积运算时数据范围的变化和精度要求,需要先将图像像素数据类型由unsigned char转换到float类型,该变换通过vtkImageCast实现,对应的设置函数SetOutputScalarTypeToFloat()。接下来需要定义卷积算子和卷积模板。vtkImageConvolve类实现图像的卷积运算,它需要两个输入。一个是需要进行卷积的图像,这里为vtkJPEGReader读取的图像数据,第二个是卷积模板数组。SetKernel5x5()函数接收一个5×5的卷积模板数组,即本例上定义的kernel数组。执行Update()后即可完成卷积运算。需要注意的是,卷积模板对应的系数之和应该为1,否则需要对计算结果进行归一化处理。另外该类中还定义了3×3和7×7的卷积模板设置函数,使用过程是一样的。卷积完成以后,再次通过vtkImageCast将float数据类型转换为unsigned char进行图像显示。均值滤波的结果如下。

 

图5.31 均值滤波

5.13.2 高斯平滑

高斯平滑的原理类似于均值滤波。均值滤波模板的系数都是一样的,而高斯平滑则是需要根据像素与模板中心的距离来定义权重。权重的计算方法是采用高斯分布,离中心越远,权重越小。

 

1:      vtkSmartPointer<vtkJPEGReader>reader =

  2:         vtkSmartPointer<vtkJPEGReader>::New();

  3:     reader->SetFileName("lena2.jpg");

  4:      reader->Update();

  5:   

  6:     vtkSmartPointer<vtkImageGaussianSmooth> gaussianSmoothFilter =

  7:         vtkSmartPointer<vtkImageGaussianSmooth>::New();

  8:     gaussianSmoothFilter->SetInputConnection(reader->GetOutputPort());

  9:      gaussianSmoothFilter->SetDimensionality(2);

 10:     gaussianSmoothFilter->SetRadiusFactor(5);

 11:     gaussianSmoothFilter->SetStandardDeviation(3);

 12:     gaussianSmoothFilter->Update();

 

上面代码中说明了怎样使用vtkImageGaussianSmooth对图像做高斯平滑。vtkImageGaussianSmooth类默认是执行三维高斯滤波,SetDimensionality()根据需要设置相应的维数。SetRadiusFactor()用于设置高斯模板的大小,当超出该模板的范围时,系数取0;SetStandardDeviation()用于设置高斯分布函数的标准差。高斯平滑效果如下所示。

 

图5.32 高斯平滑

5.13.3 中值滤波

vtkImageHybridMedian2D实现了对二维图像的中值滤波。其实现原理是,采用一个5×5的模板,逐次将模板中心对应于图像的每个像素上,将模板图像覆盖的像素的中值作为当前像素的输出值。

 

1:   vtkSmartPointer<vtkJPEGReader> reader=

  2:    vtkSmartPointer<vtkJPEGReader>::New();

  3:  reader->SetFileName("lena2.jpg");

  4:   reader->Update();

  5:   

  6:   vtkSmartPointer<vtkImageHybridMedian2D>hybridMedian =

  7:    vtkSmartPointer<vtkImageHybridMedian2D>::New();

  8:  hybridMedian->SetInput(reader->GetOutput());

  9:   hybridMedian->Update();

 

该类使用也非常简单,不需要用户设置任何参数。该方法能够有效的保持图像边缘,并对于椒盐噪声有较好的抑制作用。如下为该程序执行结果。对于三维图像,则使用vtkImageHybridMedian3D类。执行结果如下。

 

图5.33 中值滤波

5.13.4 各向异性扩散滤波

高斯平滑方法在平滑噪声的同时,模糊了图像的重要边缘图像。各向异性滤波是一种基于偏微分方程的滤波技术,建立于热量的各向异性扩散理论。各向异性滤波在图像的平坦区域选择大尺度平滑,而边缘区域则选择小尺度的平滑,在抑制噪声的同时保持了图像的边缘信息。vtkImageAnisotropicDiffusion2D(vtkImageAnisotropicDiffusion3D)实现图像的各向异性扩散滤波,使用代码如下。

 

1:    vtkSmartPointer<vtkJPEGReader> reader=

  2:     vtkSmartPointer<vtkJPEGReader>::New();

  3:    reader->SetFileName ("lena2.jpg" );

  4:  

  5:   vtkSmartPointer<vtkImageAnisotropicDiffusion2D> diffusion =

  6:      vtkSmartPointer<vtkImageAnisotropicDiffusion2D>::New();

  7:   diffusion->SetInputConnection(reader->GetOutputPort());

  8:   diffusion->SetNumberOfIterations(10);

  9:   diffusion->SetDiffusionThreshold(20);

 10:    diffusion->Update();

 

vtkImageAnisotropicDiffusion2D类通过迭代方法实现,其中SetNumberOfIterations()用于设置迭代的次数;各向异性扩散滤波原理是在梯度较小的像素处进行较大幅度扩散,而在大梯度处则只进行细微的扩散。因此需要设置一个扩算的阈值DiffusionThreshold,这个阈值与图像的梯度有关。SetDiffusionThreshold()即是用来设置扩散阈值。该类中还有一个梯度标志GradientMagnitudeThreshold,用来设置梯度算子。当该标志开时梯度通过中心差分方法计算;当标志为关时,需要单独处理每个相邻像素。当像素与相邻像素梯度小于DiffusionThreshold时进行扩散处理。下图是对lena图像进行各向异性扩散滤波处理的结果。

 

图5.34 各向异性扩散滤波


==========欢迎转载,转载时请保留该声明信息==========

版权归@东灵工作室所有,更多信息请访问东灵工作室


教程系列导航:http://blog.csdn.net/www_doling_net/article/details/8763686

================================================



© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容