基于Java實現(xiàn)空間濾波完整代碼
空間濾波的定義
濾波的本義是指信號有各種頻率的成分,濾掉不想要的成分,即為濾掉常說的噪聲,留下想要的成分,這即是濾波的過程,也是目的??臻g濾波是一種采用濾波處理的影像增強(qiáng)方法。其理論基礎(chǔ)是空間卷積和空間相關(guān)。目的是改善影像質(zhì)量,包括去除高頻噪聲與干擾,及影像邊緣增強(qiáng)、線性增強(qiáng)以及去模糊等。分為低通濾波(平滑化)、高通濾波(銳化)和帶通濾波。
圖像需要增強(qiáng)的原因
各類圖像處理系統(tǒng)在圖像的采集、獲取、傳送和轉(zhuǎn)換(如成像、復(fù)制掃描、傳輸以及顯示等)過程中,均處在復(fù)雜的環(huán)境中,光照、電磁多變,所有的圖像均不同程度地被可見或不可見的噪聲干擾。噪聲源包括電子噪聲、光子噪聲、斑點噪聲和量化噪聲。如果信噪比低于一定的水平,噪聲逐漸變成可見的顆粒形狀,導(dǎo)致圖像質(zhì)量的下降。除了視覺上質(zhì)量下降,噪聲同樣可能掩蓋重要的圖像細(xì)節(jié),在對采集到的原始圖像做進(jìn)一步的分割處理時,我們發(fā)現(xiàn)有一些分布不規(guī)律的椒鹽噪聲,為此采取相應(yīng)的對策就是對圖像進(jìn)行必要的濾波降噪處理。
(1) 中值濾波
PART/01
是將每個像元在以其為中心的M×N鄰域內(nèi)取中間亮度值來代替該像元值,以達(dá)到去尖銳“噪聲”和平滑圖像的目的。具體計算方法與模板卷積方法類似,仍采用活動窗口的掃描方法。取值時,將M×N窗口內(nèi)所有像元按亮度值的大小排列,取中間值作為中間像元的值。所以M×N取奇數(shù)為好。一般來說,圖像亮度為階梯狀變化時,取均值平滑比取中值濾波要明顯得多,而對于突出亮點的“噪聲”干擾,從去“噪聲”后對原圖的保留程度看取中值要優(yōu)于取均值。
代碼實現(xiàn):

比如我們要對下面矩陣進(jìn)行中值濾波運算,
4 4 3 7 6 8 8
4 4 3 7 6 8 8
2 2 15 8 9 9 9
5 5 8 9 13 10 10
7 7 9 12 15 11 11
8 8 11 10 14 13 13
8 8 11 10 14 13 13
輸出結(jié)果如下圖所示:

package NB;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class zzlb {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
System.out.println("請輸入矩陣的行數(shù):");
int x=s.nextInt();//獲取鍵盤輸入的數(shù)字
System.out.println("請輸入矩陣的列數(shù):");
int y=s.nextInt();//獲取鍵盤輸入的數(shù)字
int[][]b=new int[x][y];//創(chuàng)建一個二維數(shù)組
int[]p=new int[9];//創(chuàng)建一個可以存放9個元素的一維數(shù)組來獲取#3*3窗口的像元值
System.out.println("請輸入"+x+"*"+y+"的矩陣:");
for (int i = 0; i <y; i++) {
for (int j = 0; j < x; j++) {
b[i][j]=s.nextInt();//將鍵盤輸入的矩陣存放到二維數(shù)組里面
}
}
System.out.print("運算結(jié)果如下:\n");
for (int i = 1; i <y-1; i++) {
for (int j = 1; j < x-1; j++) { //鎖定到中心像元的位置,從(1,1)開始
int g=0;
for (int k =i-1; k <=i+1 ; k++) {
for (int l =j-1; l <=j+1 ; l++) {
p[g++]=b[k][l]; //將3*3矩陣窗口存儲到一維數(shù)組中
}
}
for (int k = 0; k <p.length-1; k++) {
for (int l = 0; l < p.length-1-k; l++) {
if(p[l]>p[l+1]) {
int temp = p[l];
p[l]=p[l+1];
p[l+1]=temp;//本次采用冒泡排序法對3*3窗口內(nèi)的像元從小到大排序
}
}
}
System.out.print(p[4]+" ");//輸出每個3*3模板的中心值,下標(biāo)都是4
}
System.out.println("\n");//輸出完一行就換行
}
}
}
有小伙伴看到就會說:我求的是55的矩陣,為什么輸入的是77的矩陣?原因在于我們運用的33矩陣窗口放在矩陣4個角的像元時,需要額外添加鄰近的像元來構(gòu)成33的窗口,對于這個添加的臨時像元值一般和最近的像元值保持一致。
(2)羅伯特銳化
PART/02
圖像銳化是為了突出圖像上地物的邊緣、輪廓,或某些線性目標(biāo)要素的特征。這種濾波方法提高了地物邊緣與周圍像元之間的反差,因此也被稱為邊緣增強(qiáng)。銳化的方法很多,在此只介紹羅伯特梯度。梯度反映了相鄰像元的亮度變化率,也就是說,圖像中如果存在邊緣,如湖泊、河流的邊界,山脈和道路等,則邊緣處有較大的梯度值。對于亮度值較平滑的部分,亮度梯度值較小。因此,找到梯度較大的位置,也就找到邊緣,然后再用不同的梯度計算值代替邊緣處像元的值,也就突出了邊緣,實現(xiàn)了圖像的銳化。
不過在講解之前小編先給大家引入一個新的概念——圖像卷積運算, 卷積運算:可看作是加權(quán)求和的過程,使圖像區(qū)域中的每個像素分別與卷積核(權(quán)矩陣)的每個元素對應(yīng)相乘,所有乘積之和作為區(qū)域中心像素的新值。它是在空間域上對圖像作局部檢測的運算,以實現(xiàn)平滑和銳化的目的。具體作法是選定一個卷積函數(shù),又稱為“模板”,實際上是一個M×N圖像。二維的卷積運算是在圖像中使用模板來實現(xiàn)運算的。運算方法從圖像左上角開始,選定與模板同樣大小的矩陣元素窗口,圖像窗口與模板像元對應(yīng)的亮度值相乘后再相加,最后一般將計算結(jié)果放在窗口中心位置(當(dāng)M和N都是奇數(shù)時),代替原來的像元灰度值。然后活動窗口向右移動一個像元再以同樣的方法進(jìn)行卷積運算,逐行掃描,直到全幅影像都掃描一遍,最后生成新圖像。羅伯特銳化方法使用的兩個模板如下:

F=|aidxi|+|aidyi|,其中a是矩陣中的2*2個元素,i是第i個元素,i<=4,計算結(jié)果放在左上角像元,代替之前的灰度值,但是右下角的像元模板范圍內(nèi)沒有其他像元了,無法進(jìn)行計算,為此使用羅伯特銳化方法都要在原始矩陣的最下邊和最右邊添加一行和一列,值都和最臨近的像元灰度值一樣。為了直白了斷,小編直接上例子吧,比如有某個矩陣,如下圖(1)所示,我要用上面兩個模板進(jìn)行羅伯特銳化,首先得在右邊和下邊分別添加一行和一列,如下圖(2)所示:

接下來對左上角像元進(jìn)行運算:|2*(-1)+30+40+51|+|20+3*(-1)+41+50|=4,
接下來對右上角像元進(jìn)行運算:|3*(-1)+30+50+51|+|30+3*(-1)+51+50|=4,
接下來對左下角像元進(jìn)行運算:|4*(-1)+50+40+51|+|40+5*(-1)+41+50|=2,
接下來對右下角像元進(jìn)行運算:|5*(-1)+50+50+51|+|50+5*(-1)+51+50|=0,最終輸出矩陣如下所示:

這種算法的意義在于用交叉的方法檢測出像與其領(lǐng)域在上下之間或左右之間或斜方向之間的差異,最終產(chǎn)生一個梯度影像,達(dá)到提取邊緣信息的目的。
代碼實現(xiàn):

比如我們要對下面矩陣進(jìn)行中值濾波運算,

2 2 10 10 10 10
2 2 10 10 10 10
2 2 10 10 10 10
2 2 2 2 2 2
2 2 2 2 2 2
2 2 2 2 2 2
輸出結(jié)果如下圖所示:
package NB;
import java.util.Scanner;
public class robet {
public static void main(String[] args) {
Scanner s1 = new Scanner(System.in);
System.out.println("請輸入矩陣的行數(shù):");
int x = s1.nextInt();//獲取鍵盤輸入的數(shù)字
System.out.println("請輸入矩陣的列數(shù):");
int y = s1.nextInt();//獲取鍵盤輸入的數(shù)字
int[][] b = new int[x][y];//創(chuàng)建一個二維數(shù)組
System.out.println("請輸入" + x + "*" + y + "的矩陣:");
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
b[i][j] = s1.nextInt();
}///將鍵盤輸入的矩陣存放到二維數(shù)組里面
}
for (int i =0; i <y-1; i++) {
for (int j = 0; j <x-1; j++) {
b[i][j]=Math.abs(b[i][j]-b[i+1][j+1])+Math.abs(b[i+1][j]-b[i][j+1]);
System.out.print(b[i][j]+" ");
}//對兩個模板進(jìn)行圖像卷積運算后取絕對值相加,并且把結(jié)果放到2*2窗口的左上方
System.out.println("\n");//輸出完一行就換行
}
}
}
到此這篇關(guān)于基于Java的空間濾波代碼實現(xiàn)的文章就介紹到這了,更多相關(guān)Java空間濾波內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用OTP動態(tài)口令(每分鐘變一次)進(jìn)行登錄認(rèn)證
這篇文章主要介紹了Java使用OTP動態(tài)口令(每分鐘變一次)進(jìn)行登錄認(rèn)證,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
MyBatis Plus之實現(xiàn)動態(tài)排序方式
這篇文章主要介紹了MyBatis Plus之實現(xiàn)動態(tài)排序方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02
Java?Selenium實現(xiàn)修改打開頁面窗口大小
Selenium是一個強(qiáng)大的自動化測試工具,支持多種編程語言和瀏覽器,本文將詳細(xì)介紹如何使用Java?Selenium來修改打開頁面窗口的大小,需要的可以參考下2025-01-01
SpringBoot數(shù)據(jù)庫初始化datasource配置方式
這篇文章主要為大家介紹了SpringBoot數(shù)據(jù)庫初始化datasource配置方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
SpringBoot項目運行一段時間后自動關(guān)閉的坑及解決
這篇文章主要介紹了SpringBoot項目運行一段時間后自動關(guān)閉的坑及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
SpringCloud?Feign使用ApacheHttpClient代替默認(rèn)client方式
這篇文章主要介紹了SpringCloud?Feign使用ApacheHttpClient代替默認(rèn)client方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03

