5.13 图像平滑
5.13 圖像平滑
圖像平滑常用于圖像的預處理中,如計算梯度時先對圖像進行平滑處理,可以減少噪聲對梯度的影響。圖像平滑一般是通過模板卷積運算實現。模板可以看做是一個大小為nxn的小圖像,例如3x3,5x5等等,模板的每個像素都對應一個系數值。模板卷積運算的過程是首先將模板中心依次與圖像每個像素重合,通過模板各個系數與圖像對應像素相乘來計算模板對應像素的加權平均值,最后將運算結果賦給圖像中模板中心對應的像素。
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()函數接收一個5x5的卷積模板數組,即本例上定義的kernel數組。執行Update()后即可完成卷積運算。需要注意的是,卷積模板對應的系數之和應該為1,否則需要對計算結果進行歸一化處理。另外該類中還定義了3x3和7x7的卷積模板設置函數,使用過程是一樣的。卷積完成以后,再次通過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實現了對二維圖像的中值濾波。其實現原理是,采用一個5x5的模板,逐次將模板中心對應于圖像的每個像素上,將模板圖像覆蓋的像素的中值作為當前像素的輸出值。
?
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
================================================
總結
- 上一篇: python中支持向量机的使用
- 下一篇: 5.12 边缘检测