Dekomposisi Wavelet untuk mengurangi Noise Gambar

By | June 18, 2023
Print Friendly, PDF & Email
288 Views

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

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

See also  Decompose Citra dalam bit-planes

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

See also  Contour Retrieval Mode

 

 

Leave a Reply