首页 > 其他分享 >VTK_Learning_图像平滑_均值滤波器_高斯滤波器__中值滤波器_各向异性滤波

VTK_Learning_图像平滑_均值滤波器_高斯滤波器__中值滤波器_各向异性滤波

时间:2022-12-30 13:01:38浏览次数:48  
标签:__ 滤波器 rw 1.0 VTK 0.04 vtkSmartPointer New include


1.均值滤波

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

下面代码说明了怎样使用vtkImageConvolve类来实现图像的均值滤波:
 

#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); #include <vtkSmartPointer.h> #include <vtkJPEGReader.h> #include <vtkImageCast.h> //图像数据类型转换为计算类型 #include <vtkImageData.h> #include <vtkImageConvolve.h> //图像卷积运行 #include <vtkImageShiftScale.h> //设置像素值范围 //#include <vtkImageMandelbrotSource.h> #include <vtkImageActor.h> #include <vtkRenderer.h> #include <vtkImageMandelbrotSource.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkInteractorStyleImage.h> int main() { vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New(); reader->SetFileName("lena.jpg"); reader->Update(); vtkSmartPointer<vtkImageCast> originalCastFilter = vtkSmartPointer<vtkImageCast>::New(); originalCastFilter->SetInputConnection(reader->GetOutputPort()); //建管线 originalCastFilter->SetOutputScalarTypeToFloat(); //设置属性 originalCastFilter->Update(); vtkSmartPointer<vtkImageConvolve> convolveFilter = vtkSmartPointer<vtkImageConvolve>::New(); convolveFilter->SetInputConnection(originalCastFilter->GetOutputPort()); //建管线 double kernel[25] = { 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04 }; convolveFilter->SetKernel5x5(kernel); convolveFilter->Update(); vtkSmartPointer<vtkImageCast> convCastFilter = vtkSmartPointer<vtkImageCast>::New(); convCastFilter->SetInputData(convolveFilter->GetOutput()); convCastFilter->SetOutputScalarTypeToUnsignedChar(); //转换为图像数据 convCastFilter->Update(); /// vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New(); originalActor->SetInputData(reader->GetOutput()); vtkSmartPointer<vtkImageActor> convolvedActor = vtkSmartPointer<vtkImageActor>::New(); convolvedActor->SetInputData(convCastFilter->GetOutput()); double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 }; double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 }; vtkSmartPointer<vtkRenderer> originalRenderer = vtkSmartPointer<vtkRenderer>::New(); originalRenderer->SetViewport(leftViewport); originalRenderer->AddActor(originalActor); originalRenderer->SetBackground(1.0, 1.0, 1.0); originalRenderer->ResetCamera(); vtkSmartPointer<vtkRenderer> convolvedRenderer = vtkSmartPointer<vtkRenderer>::New(); convolvedRenderer->SetViewport(rightViewport); convolvedRenderer->AddActor(convolvedActor); convolvedRenderer->SetBackground(1.0, 1.0, 1.0); convolvedRenderer->ResetCamera(); vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New();; rw->AddRenderer(originalRenderer); rw->AddRenderer(convolvedRenderer); rw->SetSize(640, 320); rw->Render(); rw->SetWindowName("Smooth by MeanFilter"); vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New(); rwi->SetInteractorStyle(style); rwi->SetRenderWindow(rw); rwi->Initialize(); rwi->Start(); return 0; }

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

VTK_Learning_图像平滑_均值滤波器_高斯滤波器__中值滤波器_各向异性滤波_图像平滑

 2.高斯滤波

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

下面是一个利用Gauss滤波进行图像平滑的实例:

#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); #include <vtkSmartPointer.h> #include <vtkJPEGReader.h> #include <vtkImageCast.h> #include <vtkImageData.h> #include <vtkImageGaussianSmooth.h> #include <vtkImageActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkInteractorStyleImage.h> //#include <vtkImageEllipsoidSource.h> int main() { vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New(); reader->SetFileName("lena.jpg"); reader->Update(); vtkSmartPointer<vtkImageGaussianSmooth> gaussianSmoothFilter = vtkSmartPointer<vtkImageGaussianSmooth>::New(); gaussianSmoothFilter->SetInputConnection(reader->GetOutputPort()); gaussianSmoothFilter->SetDimensionality(2); gaussianSmoothFilter->SetRadiusFactor(5); //设置模板范围 gaussianSmoothFilter->SetStandardDeviation(3);//正态分布/高斯分布标准差 gaussianSmoothFilter->Update(); vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New(); originalActor->SetInputData(reader->GetOutput()); vtkSmartPointer<vtkImageActor> smoothedActor = vtkSmartPointer<vtkImageActor>::New(); smoothedActor->SetInputData(gaussianSmoothFilter->GetOutput()); double originalViewport[4] = { 0.0, 0.0, 0.5, 1.0 }; double smoothedViewport[4] = { 0.5, 0.0, 1.0, 1.0 }; vtkSmartPointer<vtkRenderer> originalRenderer = vtkSmartPointer<vtkRenderer>::New(); originalRenderer->SetViewport(originalViewport); originalRenderer->AddActor(originalActor); originalRenderer->ResetCamera(); originalRenderer->SetBackground(1.0, 0, 0); vtkSmartPointer<vtkRenderer> gradientMagnitudeRenderer = vtkSmartPointer<vtkRenderer>::New(); gradientMagnitudeRenderer->SetViewport(smoothedViewport); gradientMagnitudeRenderer->AddActor(smoothedActor); gradientMagnitudeRenderer->ResetCamera(); gradientMagnitudeRenderer->SetBackground(1.0, 1.0, 1.0); vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New(); rw->AddRenderer(originalRenderer); rw->AddRenderer(gradientMagnitudeRenderer); rw->SetSize(640, 320); rw->SetWindowName("Smooth by Gaussian"); vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New(); rwi->SetInteractorStyle(style); rwi->SetRenderWindow(rw); rwi->Initialize(); rwi->Start(); return 0; }

vtkImageGaussianSmooth类默认是执行三维高斯滤波;
SetDimensionality()根据需要设置相应的维数;
SetRadiusFactor()用于设置高斯模板的大小,当超出该模板的范围时,系数取0;
SetStandardDeviation()用于设置高斯分布函数的标准差。
高斯平滑效果如下所示:

VTK_Learning_图像平滑_均值滤波器_高斯滤波器__中值滤波器_各向异性滤波__中值滤波器_02

3.中值滤波

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

#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); #include <vtkSmartPointer.h> #include <vtkJPEGReader.h> #include <vtkImageData.h> #include <vtkImageCast.h> #include <vtkImageHybridMedian2D.h> #include <vtkImageActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkInteractorStyleImage.h> int main(int argc, char* argv[]) { vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New(); reader->SetFileName("lena.jpg"); reader->Update(); vtkSmartPointer<vtkImageHybridMedian2D> hybridMedian = vtkSmartPointer<vtkImageHybridMedian2D>::New(); hybridMedian->SetInputData(reader->GetOutput()); hybridMedian->Update(); /// vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New(); originalActor->SetInputData(reader->GetOutput()); vtkSmartPointer<vtkImageActor> hybridMedianActor = vtkSmartPointer<vtkImageActor>::New(); hybridMedianActor->SetInputData(hybridMedian->GetOutput()); / double originalViewport[4] = { 0.0, 0.0, 0.5, 1.0 }; double hybridMedianViewport[4] = { 0.5, 0.0, 1.0, 1.0 }; vtkSmartPointer<vtkRenderer> originalRenderer = vtkSmartPointer<vtkRenderer>::New(); originalRenderer->SetViewport(originalViewport); originalRenderer->AddActor(originalActor); originalRenderer->ResetCamera(); originalRenderer->SetBackground(1.0,0,0); vtkSmartPointer<vtkRenderer> hybridMedianRenderer = vtkSmartPointer<vtkRenderer>::New(); hybridMedianRenderer->SetViewport(hybridMedianViewport); hybridMedianRenderer->AddActor(hybridMedianActor); hybridMedianRenderer->ResetCamera(); hybridMedianRenderer->SetBackground(1.0, 1.0, 1.0); // vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New(); rw->AddRenderer(originalRenderer); rw->AddRenderer(hybridMedianRenderer); rw->SetSize(640, 320); rw->Render(); rw->SetWindowName("MedianFilterExample"); vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New(); rwi->SetInteractorStyle(style); rwi->SetRenderWindow(rw); rwi->Initialize(); rwi->Start(); return 0; }

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

执行结果如下:

 

VTK_Learning_图像平滑_均值滤波器_高斯滤波器__中值滤波器_各向异性滤波_均值滤波器_03

4.各向异性扩散滤波

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

#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); #include <vtkSmartPointer.h> #include <vtkJPEGReader.h> #include <vtkImageCast.h> #include <vtkImageAnisotropicDiffusion2D.h> #include <vtkImageActor.h> #include <vtkCamera.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkInteractorStyleImage.h> int main() { vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New(); reader->SetFileName("lena.jpg"); vtkSmartPointer<vtkImageAnisotropicDiffusion2D> diffusion = vtkSmartPointer<vtkImageAnisotropicDiffusion2D>::New(); diffusion->SetInputConnection(reader->GetOutputPort()); diffusion->SetNumberOfIterations(100); diffusion->SetDiffusionThreshold(5); //小于该阈值扩散 diffusion->Update(); / vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New(); originalActor->SetInputData(reader->GetOutput()); vtkSmartPointer<vtkImageActor> diffusionActor = vtkSmartPointer<vtkImageActor>::New(); diffusionActor->SetInputData(diffusion->GetOutput()); double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 }; double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 }; vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New(); vtkSmartPointer<vtkRenderer> leftRenderer = vtkSmartPointer<vtkRenderer>::New(); leftRenderer->SetViewport(leftViewport); leftRenderer->AddActor(originalActor); leftRenderer->SetBackground(1.0, 0, 0); leftRenderer->SetActiveCamera(camera); leftRenderer->ResetCamera(); vtkSmartPointer<vtkRenderer> rightRenderer = vtkSmartPointer<vtkRenderer>::New(); rightRenderer->SetViewport(rightViewport); rightRenderer->SetBackground(1.0, 1.0, 1.0); rightRenderer->AddActor(diffusionActor); rightRenderer->SetActiveCamera(camera); / vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New(); rw->AddRenderer(leftRenderer); rw->AddRenderer(rightRenderer); rw->SetSize(640, 320); rw->SetWindowName("Smooth by AnistropicFilter"); vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New(); rwi->SetInteractorStyle(style); rwi->SetRenderWindow(rw); rwi->Initialize(); rwi->Start(); return 0; }

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

VTK_Learning_图像平滑_均值滤波器_高斯滤波器__中值滤波器_各向异性滤波_高斯滤波器_04

标签:__,滤波器,rw,1.0,VTK,0.04,vtkSmartPointer,New,include
From: https://blog.51cto.com/u_15926338/5980094

相关文章

  • KSN2021
    我是印度尼西亚老哥!D1T1题意给定一个长度为\(N\)字符集为\(\{{\texttt?},{\textttA},{\textttB}\}\)的字符串,求将每个\(\texttt?\)替换为\(\textttA\)或\(......
  • VTK_Learning_图像像素的访问与修改
    1.直接访问图像像素(索引法)#include<vtkAutoInit.h>VTK_MODULE_INIT(vtkRenderingOpenGL2);#include<vtkSmartPointer.h>#include<vtkImageData.h>#include<vtkBMPReade......
  • VTK_Learning_图像基本操作_彩色图像生成灰度图像_彩色图像成分提取
    1.灰度图像映射vtkImageLuminance负责将一个RGB彩色图像转换为一个单组分的灰度图像。映射公式如下:luminance=0.3*R+0.59*G+0.11*B该公式中,R为输入图像的第一分量(红......
  • Azure DevOps Server 2019 (TFS)安装教程
    (1)安装教程:​​AzureDevOpsServer2019(TFS)安装教程-danzhang​​AzureDevOpsServer的安装教程_躺平佛系周大侠的博客1.配置数据库,使用默认的sqlexpress2.搜索配置......
  • tep1.0.0正式版发布且将不再维护
    写在前面根据pypistats统计,tep在pypi的下载量达到了1w,对于纯个人研发的一款测试小工具来说,已经算不错了,要知道HttpRunner也才6w啊。tep可以说是我在接口自动化测试这个领......
  • Opnecv_遍历Mat
    opencv图像数据是BGR的顺序,其它的通常为RGB的顺序。Theefficientway Mat&ScanImageAndReduceC(Mat&I,constuchar*consttable){//acceptonlychartypematri......
  • VTK_Learning_VTK开发理论汇总
    一、VTK开发基础_智能指针与引用计数 二、VTK开发基础_vtkObject类深入分析 三、VTK管线机制_信息对象类VTKInformation 四、Pipeline管线执行模型 ......
  • Qt总结
    (1)app的生命周期长于组件的的生命周期。否则这可是Qt编程的大忌,下面是错误的例子。#include<QApplication>#include<QLabel>intmain(intargc,char*argv[]){QA......
  • [蓝桥杯 2013 省 A] 剪格子
    [蓝桥杯2013省A]剪格子注意事项:读入顺序为m,n#include<iostream>usingnamespacestd;constintN=11;intn,m;intw[N][N];intdx[4]={-1,0,1,0}......
  • VTK_Learning_三维图像切片(二)———鼠标交互(回调函数、观察者-命令模式)
    学习三维图像切面的提取后,我们可以实现一个稍微复杂的程序——通过滑动鼠标来切换三维图像切片,这也是医学图像处理软件中一个很基本的功能。实现该功能难点是怎样在VTK中控......