Pada postingan sebelumnya telah dibahas mengenai jenis noise yang sering dijumpai secara umum yaitu salt noise. Salt noise cukup mengganggu sekali oleh sebab itu ada beberapa cara yang bisa kita gunakan. Salah satunya yaitu dekomposisi wavelet. Pembahasan mengenai transformasi wavelet bisa kalian pelajari sendiri di google.
Untuk mensimulasikan Dekomposisi Wavelet untuk mengurangi Noise Gambar kita bisa menggunakan salt noise sebagai contoh, nanti kita juga akan membandingkan metode lain untuk mengurangi noise melalui median filter. Ok langsung saja, kita akan mencoba membuat noise pada sebuah citra (format grayscale saja) menggunakan function add_noise. Seperti pada gambar berikut ini
import random import cv2 import numpy as np from matplotlib import pyplot as plt from skimage.metrics import peak_signal_noise_ratio as psnr def add_noise(img): img2 = img.copy() if img.ndim==3: row,col,dim = img.shape else: row,col = img.shape koordinat = np.random.rand(row,col) img2[koordinat>0.5]=0 koordinat = np.random.rand(row,col) img2[koordinat<0.1] = 255 return img2 img = cv2.imread('gambar.jpg',0) #dibaca sebagai gray img2 = add_noise(img) plt.close('all') plt.figure() plt.imshow(cv2.cvtColor(np.hstack((img,img2)), cv2.COLOR_BGR2RGB)) plt.show() print("nilai PSNR: ",psnr(img,img2))
dengan nilai PSNR nya : 6.91 yang artinya ada banyak noise didalam gambar tersebut!
Dekomposisi Wavelet
Contents
Tentu kita membutuhkan library untuk melakukan dekomposisi wavelet yaitu pywavelet, langsung saja kita panggil library
import pywt from pywt import wavedec
Lakukan dekomposisi terlebih dahulu
noisy = img2.copy() LL, (LH, HL, HH) = pywt.dwt2(noisy, 'db32')
Mari kita tampilkan ke 4 komponen diatas
titles = ['Approximation', ' Horizontal detail', 'Vertical detail', 'Diagonal detail'] fig, ax = plt.subplots(nrows=1, ncols=4, figsize=(20, 15)) for i, a in enumerate([LL, LH, HL, HH]): ax[i].imshow(a, cmap=plt.cm.gray) ax[i].set_title(titles[i], fontsize=10) ax[i].set_xticks([]) ax[i].set_yticks([]) fig.tight_layout() plt.show()
Dekomposisi wavelet nya yaitu
langkah selanjutnya melakukan invers dekomposisi wavelet dengan menghilangkan komponen HH
denoised1 = pywt.idwt2((LL, (LH, HL, None)), 'db32')
titles = ['original','noisy', 'denoised'] fig, ax = plt.subplots(nrows=1, ncols=len(titles), figsize=(15, 10)) for i, a in enumerate([img,noisy, denoised1]): ax[i].imshow(a, cmap=plt.cm.gray) ax[i].set_title(titles[i], fontsize=10) ax[i].set_xticks([]) ax[i].set_yticks([]) fig.tight_layout() plt.show()
Hasilnya yaitu
Kita akan menghitung nilai PSNR (harusnya nilai lebih tinggi dari sebelumnya)
print("nilai PSNR: ",psnr(img,np.uint8(denoised1[0:img.shape[0],:])))
Hasilnya yaitu 8.5 yang artinya Dekomposisi Wavelet dapat digunakan untuk mengurangi Noise Gambar
Mencoba Denoising dengan Median filter
Mari kita coba untuk teknik denoising yang sederhana yaitu median filter
img_median = cv2.medianBlur(img2, 3) # Add median filter to image
Kita tampilkan
titles = ['original','noisy', 'denoised by median filter'] fig, ax = plt.subplots(nrows=1, ncols=len(titles), figsize=(15, 10)) for i, a in enumerate([img,img2, img_median]): ax[i].imshow(a, cmap=plt.cm.gray) ax[i].set_title(titles[i], fontsize=10) ax[i].set_xticks([]) ax[i].set_yticks([]) fig.tight_layout() plt.show()
Hasilnya
Mungkin secara sekilas lebih rapi hasil denoising menggunakan dekomposisi wavelet dan itu dibuktikan dengan nilai PSNR nya juga lebih kecil dari dekomposisi wavelet yaitu 8.06
print("nilai PSNR: ",psnr(img,img_median))
Denoising menggunakan Deep Learning
Sebenarnya untuk denoising yang lebih baik, bisa kalian coba menggunakan AI – Deep Learning namun kita wajib menggunakan dataset yang sangat besar. Arsitektur yang bisa kalian coba dari awal yaitu Autoencoder
https://ietresearch.onlinelibrary.wiley.com/doi/10.1049/iet-ipr.2018.6004
ref:
https://iust-projects.ir/post/dip04/
https://medium.com/@florestony5454/median-filtering-with-python-and-opencv-2bce390be0d1
Noise pada Sinyal
Penerapan wavelet akan semakin mudah kalau kita ilustrasikan pada data sinyal. Misalkan kita punya data sinyal sinus dengan 3 frekuensi per detik serta adanya noise random
fs = 100 #sample rate nya! t = np.arange(0,1,1/fs) f1 = 3 #jumlah frekuensi dalam 1 detik signal = np.sin(2*np.pi*f1*t) noise = np.random.normal(0,0.1, signal.shape[0]) signal_noise = signal+noise plot(t,signal_noise) plot(t,signal)
Kita akan mencoba menghaluskan sinyal yang terkena noise dengan menghilangkan nilai D dan lakukan thresholding nilainya dengan komponen wavelet yaitu
- A: aproksimasi
- D: detail
cA,cD = pywt.dwt(signal_noise, 'sym5',mode='symmetric') cD = pywt.threshold(cD,0.8) denoised1 = pywt.idwt(cA,cD, 'sym5',mode='symmetric') denoised2 = pywt.idwt(cA,None, 'sym5',mode='symmetric')
Yuk sekalian kita lihat komponen A dan D serta hasil rekonstruksinya
fig, ax = plt.subplots(figsize=(8,4)) ax.plot(cA, label='cA') ax.plot(cD, label='cD', linestyle='--',color='black') ax.legend(loc='upper left') ax.set_title('Komponen cA dan cD') plt.show() fig, ax = plt.subplots(figsize=(8,4)) ax.plot(signal_noise, label='signal') ax.plot(denoised2, label='reconstructed signal', linestyle='--',color='black') ax.legend(loc='upper left') ax.set_title('Sinyal rekonstruksi jika komponen D >0.8') plt.show() fig, ax = plt.subplots(figsize=(8,4)) ax.plot(signal_noise, label='signal') ax.plot(denoised3, label='reconstructed signal', linestyle='--',color='black') ax.legend(loc='upper left') ax.set_title('Sinyal Jika Dihilangkan komponen cD') plt.show()
Kalian bisa melihat bahwa sinyal lebih halus/smooth