1. 程式人生 > >opencv學習(二十一)之中值濾波medianBlur

opencv學習(二十一)之中值濾波medianBlur

中值濾波是一種典型的非線性濾波,是基於排序統計理論的一種能夠有效抑制噪聲的非線性訊號處理技術,基本思想是用畫素點鄰域灰度值的中值來代替該畫素點的灰度值,讓周圍的畫素值接近真實的值從而消除孤立的噪聲點。該方法在取出脈衝噪聲、椒鹽噪聲的同時能保留影象的邊緣細節。這些優良特性是線性濾波所不具備的。
中值濾波首先也得生成一個濾波模板,將該模板內的各畫素值進行排序,生成單調上升或單調下降的二維資料序列,二維中值濾波輸出為g(x, y)=medf{f(x-k, y-1),(k, l∈w)},其中f(x,y)和g(x,y)分別是原影象和處理後圖像, w為輸入的二維模板,能夠在整幅影象上滑動,通常尺寸為3*3或5*5區域,也可以是不同的形狀如線狀、圓形、十字形、圓環形等。通過從影象中的二維模板取出奇數個數據進行排序,用排序後的中值取代要處理的資料即可。
中值濾波對消除椒鹽噪聲非常有效,能夠克服線性濾波器帶來的影象細節模糊等弊端,能夠有效保護影象邊緣資訊,是非常經典的平滑噪聲處理方法。在光學測量條紋影象的香味分析處理方法中有特殊作用,但在條紋中心分析方法中作用不大。
中值濾波相較於線性濾波中的均值濾波優點在前面已經提到,取得良好濾波效果的代價就是耗時的提升,可能達到均值濾波的數倍,而且對於細節較多的影象也不太適用。
opencv中提供了medianBlur()函式實現了中值濾波操作,其原型如下:

C++: void medianBlur(InputArray src, OutputArray dst, int ksize)

引數解釋:
. InputArray src: 輸入影象,影象為1、3、4通道的影象,當模板尺寸為3或5時,影象深度只能為CV_8U、CV_16U、CV_32F中的一個,如而對於較大孔徑尺寸的圖片,影象深度只能是CV_8U。
. OutputArray dst: 輸出影象,尺寸和型別與輸入影象一致,可以使用Mat::Clone以原影象為模板來初始化輸出影象dst
. int ksize: 濾波模板的尺寸大小,必須是大於1的奇數,如3、5、7……

示例程式:

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

//定義全域性變數
Mat g_mSrcImage;
Mat g_mDstImage;
const int g_nMedianBlurMaxValue = 5;
int g_nMedianBlurValue;
int g_nkernelSize;

//定義回撥函式
void on_medianBlurTrackBar(int, void*); int main() { g_mSrcImage = imread("lena.jpg"); //判斷檔案是否載入成功 if(g_mSrcImage.empty()) { cout << "影象載入失敗!" << endl; return -1; } else cout << "影象載入成功!" << endl; //判斷影象是否是CV_8U影象 if(0 <= g_mSrcImage.depth() <= 255) cout << "載入影象符合處理要求!" << endl; else { cout << "影象深度不是CV_8U,程式即將退出..." << endl; return -1; } namedWindow("原影象", WINDOW_AUTOSIZE); imshow("原影象", g_mSrcImage); //輸出影象視窗屬性及軌跡條名稱 namedWindow("中值濾波影象", WINDOW_AUTOSIZE); char medianBlurName[20]; sprintf(medianBlurName, "核函式尺寸 %d", g_nMedianBlurMaxValue); g_nMedianBlurValue = 1; //建立軌跡條 createTrackbar(medianBlurName, "中值濾波影象", &g_nMedianBlurValue, g_nMedianBlurMaxValue, on_medianBlurTrackBar); on_medianBlurTrackBar(g_nMedianBlurValue, 0); waitKey(0); return 0; } void on_medianBlurTrackBar(int, void*) { //重新計算尺寸值,尺寸值應為大於1的奇數 g_nkernelSize = g_nMedianBlurValue * 2 + 1; medianBlur(g_mSrcImage, g_mDstImage, g_nkernelSize); imshow("中值濾波影象", g_mDstImage); }

執行結果:
這裡寫圖片描述

程式說明:
對於程式中對影象深度的判斷根據如下標準:


    CV_8U - 8-bit unsigned integers ( 0..255 )
    CV_8S - 8-bit signed integers ( -128..127 )
    CV_16U - 16-bit unsigned integers ( 0..65535 )
    CV_16S - 16-bit signed integers ( -32768..32767 )
    CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
    CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
    CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )