欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

VTK修炼之道36:图像平滑_均值滤波器

发布时间:2025/3/15 30 豆豆
生活随笔 收集整理的这篇文章主要介绍了 VTK修炼之道36:图像平滑_均值滤波器 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

1.图像平滑

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

2.均值滤波

均值滤波是一种经常用到的平滑方法,其对应的模板各个像素的值为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进行图像显示。

均值滤波的结果如下:

2.参看资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.

总结

以上是生活随笔为你收集整理的VTK修炼之道36:图像平滑_均值滤波器的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。