ETH官方钱包

切換
舊版
前往
大廳
主題

數位影像處理_歧異點方法

萬念俱灰的人最強 | 2019-07-22 01:48:31 | 巴幣 2 | 人氣 543


歧異點方法
1.   選擇閥值D。
2.   比較指定像素值P和周圍8個像素的平均值m。
3.   若是|p-m|>D,則認定該像素為雜訊,反之則否。
4.   若像素為雜訊,則用m取代,反之則保留原數值。

(原圖格式tif,由於巴哈限制轉成jpg)

會使用到這個方法就不得不提一提椒鹽雜訊(Salt and pepper noise),聽的都讓人餓。又稱之為脈衝雜訊,聽起來還真牛逼。
可能是因為影像訊號受到突如其來的強烈干擾而產生,呈現方式是整個影像任意散佈了黑色或白色的像素,看起來就像打翻胡椒鹽那樣子。
(此程式使用的兩張圖片)

歧異點方法
此圖內容取自:Digital Image Processing with Matlab

概念是在圖片中的每個像素,假設此點的灰階值比其他四周8個相鄰的平均灰階值還要高的話,我們就認為他是雜訊,並且將雜訊值換成8個相鄰平均灰階值。

也就是我們看到的
f =  {
[0.125 0.125 0.125]
[0.125 0   0.125]
[0.125 0.125 0.125]
}
為什麼是0.125,而不是別的數字?你看你把1分成8等分,不就是0.125嘛!


程式說明:
import cv2
import numpy as np
import matplotlib.pyplot as plt
import scipy.signal
cv2 -> opencv  一個跨平臺的電腦視覺庫,跟影像有關的都蠻好用的。
numpy -> Python語言的一個擴充程式庫。支援高階大量的維度陣列與矩陣運算,此外也針對陣列運算提供大量的數學函式函式庫,圖片本身就是陣列的一種。
matplotlib.pyplot -> Python程式語言及其數值數學擴展包,用來將資料視覺化。
scipy.signal ->Scipy數值積分計算用,我也不是很熟

# 讀完後 由於圖片本身是灰階圖 所以他們的RGB值都是同一個 取用其中一個就好
gray0 = twin0[:,:,0]
gray2 = twin2[:,:,0]
# 把轉換完的圖片複製
t0clone = gray0.copy()
t2clone = gray2.copy()
d = 0.2125     # 閥值
閥值的部分可以自己調整
f = np.array([[0.125,0.125,0.125],[0.125,0,0.125],[0.125,0.125,0.125]])
out0 = cv2.normalize(t0clone.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX)   # img2double
out2 = cv2.normalize(t2clone.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX)   # img2double
t0clone = scipy.signal.convolve2d(out0, np.rot90(f,2), 'valid')                  # 濾波濾起來
t2clone = scipy.signal.convolve2d(out2, np.rot90(f,2), 'valid')                  # 濾波濾起來

'''
將t0clone 用f濾波 濾波之後 和原圖比較 超過閥值->替換
'''
for i in range(t0clone.shape[0]):
    for j in range(t0clone.shape[1]):
        if(abs(t0clone[i][j]-out0[i][j])>d):
            out0[i][j]=t0clone[i][j]

for i in range(t2clone.shape[0]):
    for j in range(t2clone.shape[1]):
        if(abs(t2clone[i][j]-out2[i][j])>d):
            out2[i][j]=t2clone[i][j]
我的個人想法是把複製過來的圖直接先以f進行濾波,再以濾波結束後的數值跟原圖進行比較,
超過D值認為是雜訊,並且換掉。

完整程式碼:
import cv2
import numpy as np
import matplotlib.pyplot as plt
import scipy.signal

# 先讀圖作業的兩張圖片
twin0 = cv2.imread('twins_sp.png')
twin2= cv2.imread('twins_sp1.png')

# 讀完後 由於圖片本身是灰階圖 所以他們的RGB值都是同一個 為了方便運算 就取用其中一個
gray0 = twin0[:,:,0]
gray2 = twin2[:,:,0]


t0clone = gray0.copy()
t2clone = gray2.copy()

d = 0.2125     # 閥值

# 建立窗口
plt.figure()

f = np.array([[0.125,0.125,0.125],[0.125,0,0.125],[0.125,0.125,0.125]])
out0 = cv2.normalize(t0clone.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX)   # img2double
out2 = cv2.normalize(t2clone.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX)   # img2double
t0clone = scipy.signal.convolve2d(out0, np.rot90(f,2), 'valid')                  # 濾波濾起來
t2clone = scipy.signal.convolve2d(out2, np.rot90(f,2), 'valid')                  # 濾波濾起來

'''
將t0clone 用f濾波 濾波之後 和原圖比較 超過閥值->替換
'''
for i in range(t0clone.shape[0]):
    for j in range(t0clone.shape[1]):
        if(abs(t0clone[i][j]-out0[i][j])>d):
            out0[i][j]=t0clone[i][j]

for i in range(t2clone.shape[0]):
    for j in range(t2clone.shape[1]):
        if(abs(t2clone[i][j]-out2[i][j])>d):
            out2[i][j]=t2clone[i][j]

# plt.axis('off') 不顯示其座標
plt.subplot(2,2,1)
plt.title('origin0')
plt.imshow(twin0)
plt.axis('off')

plt.subplot(2, 2, 2)
plt.title('out0')
plt.imshow(out0,cmap=plt.cm.gray)       #若是不加上 cmap=plt.cm.gray 將顯示RGB中的G
plt.axis('off')

plt.subplot(2,2,3)
plt.title('origin2')
plt.imshow(twin2)
plt.axis('off')

plt.subplot(2, 2, 4)
plt.title('out2')
plt.imshow(out2,cmap=plt.cm.gray)       #若是不加上 cmap=plt.cm.gray 將顯示RGB中的G
plt.axis('off')

plt.show()

cv2.waitKey(0)

參考資料:
https://stackoverflow.com/questions/43270274/equivalent-of-matlab-filter2filter-image-valid-in-python
https://stackoverflow.com/questions/29100722/equivalent-im2double-function-in-opencv-python
https://www.cnblogs.com/denny402/p/5122594.html

希望對大家有所幫助

創作回應

超胖小小牛
好可憐
2019-07-23 01:02:30

更多創作