1. 程式人生 > >Java資料處理之中值濾波演算法

Java資料處理之中值濾波演算法

一般而言,對於硬體收集來的各種資料都是要進行濾波的,濾波的手法有很多種,只是一般都不會在java層進行。但是也有一些特別小巧實用易懂的方法,可以用來對資料進行濾波,譬如中值濾波演算法。

  該演算法在波形類資料中經常會用上,主要效果是突出特徵波形,使得波形更加”凹凸有致“。但是也有一定副作用,那就是如果波形本身就非常漂亮,那就有可能將其特徵波形稍稍磨平——當然這種效果基本還是在能接受範圍內。

  中值濾波演算法主要思路是,對於心電資料中的某一個點n,選取一個周圍的長度為N的區間(從搜尋到的論文資料來看,該區間的選擇有在該點之後也有在該點之前,可見對於區間的選取並不是固定的,要通過結果來對比效果如何,本文最後選擇的是[x-m,x+m]

),然後對該區間內的數進行排序,取中間的值作為該點對應的漂移值,然後用n減去該值即是濾波後的值。

       設心電波形的函式為f(x),取區間[x-m,x+m]的值進行排序,設mid[n-m,n+m]為區間內排序後處於中間的數,則f(mid[n-m,n+m])則是對應的漂移值。將式子串起來易得:

n'=n-f(mid[x-m,x+m])

      由上述式子可見,基本上沒有複雜的運算,但是對於m值的選取需要大家好好斟酌——m選得太大,一方面需要拋棄的點會更多(由式子可知心電資料開始和結尾的m個點無法進行濾波,也就是說這2m個點必須被拋棄,否則會引起和濾波後的資料放在一起組成心電波形的話會引起誤檢),另一方面會加大系統的負擔,雖然排序的時間複雜度不高,但是因為每個點都要跟前後m

個數據進行排序,因此m值每增大一點,系統負擔就會增大一分。而如果m選得太小,可想而知該漂移值被噪聲和波動影響的成分會大得多,具體表現就是使得濾波後的波形失真較嚴重,可能會引起更嚴重的誤檢。

  將上述思路寫成java程式碼,大致如下:

            for(int i=45;i<dataY.size()-45;i++){
                List<Float> sortList=new ArrayList<Float>(dataY.subList(i-45, i+45));
                Collections.sort(sortList);
                float mid=sortList.get(sortList.size()/2);
                newDataListY.add((dataY.get(i)-mid));
            }
從程式碼可以非常清楚地知道,這個演算法有多簡潔了^_^而且由於java自帶的排序演算法,所以又幫我們省了不少時間~

   結果對比:

濾波前


濾波後

對於一個這麼廉價的演算法,這個結果已經非常能接受了~