中值濾波器原理
如果不在邊緣區域,圖像的數據是平緩的,沒有太大的差值。因此,一個噪聲點的值要么過大,要么過小。比如下圖,左圖是沒有處理的原圖,250在該區域由為突出,通過對3*3的9個數據進行排序,將中間值150重新填入,即濾波完成,原本的噪聲點被去掉,該區域恢復平緩。同理,在邊緣區域中,對於邊界來說,高頻不會影響,而過低數值將會突出,中值的選擇將不會受到影響,除非3*3的整塊區域都被污染,這時我們可以考慮更大的核來處理。
java 實現
/**
* <p>Title: medfilt2</p>
* <p>Description:中值濾波 </p>
* @param imagesPos
* @param tmp 模板矩陣 2*2
* @return
*/
public static Matrix medfilt2(Matrix imagesPos, Matrix tmp) {
/**imagesPos 計算矩陣外圍追加數值為0外圍,以防矩陣下表越界*/
Matrix appendPos=DenseMatrix.Factory.emptyMatrix();
appendPos=appendPos.appendVertically(Ret.NEW, imagesPos);
Matrix v= DenseMatrix.Factory.zeros(1,imagesPos.getColumnCount());
appendPos=appendPos.appendVertically(Ret.NEW, v);
Matrix h= DenseMatrix.Factory.zeros(imagesPos.getRowCount()+1,1);
appendPos=appendPos.appendHorizontally(Ret.NEW, h);
Matrix matRt= DenseMatrix.Factory.zeros(imagesPos.getRowCount(),imagesPos.getColumnCount());
for(int i=0;i<imagesPos.getRowCount();i++) {
Matrix matTmp= DenseMatrix.Factory.zeros(tmp.getColumnCount(), tmp.getColumnCount());
for(int j=0;j<imagesPos.getColumnCount();j++) {
/**求和*/
double [] d= {appendPos.getAsDouble(i,j),appendPos.getAsDouble(i,j+1),
appendPos.getAsDouble(i+1,j),appendPos.getAsDouble(i+1,j+1)};
Arrays.sort(d);
/**依據模板矩陣2*2 計算中值*/
double dbMid=(d[1]+d[2])/2;
matRt.setAsDouble(dbMid, i,j);
}
}
return matRt;
}