A fényképek egyik nem kívánt módosulása a zaj, amelyet azért nehéz utólag szűrni, mert elmosással könnyen a képen lévő élek is eltűnhetnek. Olyan módszerekre van szükség, amelyek a zajt, azaz a szomszédos pixelek közötti különbséget úgy találják meg és tüntetik el, hogy közben a fontos élek, amelyek szintén szomszédos pixelek közötti különbségek, maradjanak érintetlenek. Manapság elterjedt az AI-alapú zajszűrés, amely képek millióin tanulta meg milyen a zajos és a tiszta kép, de számos klasszikus módszer is használatos.
Minden pixel adott méretű környezetében meg kell keresni az értékeknek a mediánját, azaz a sorba rendezett adatsor középső értékét, amely a pixel új értéke lesz. Mivel a legjellemzőbb színt adja meg minden helyen, így nem mossa el a széleket, de eltünteti a zajokat. Az eredmény nagyon érzékeny a kiválasztott ablakméretre.
Tulajdonképpen egy Gauss-görbével történő elmosás, de a konvolúciós kernel elemeinek hatása a vizsgált pixelhez képest mérhető intenzitáskülönbségen alapuló súlyozott átlag szerint alakul. A homogén részeknél érvényesül a simító hatás, miközben a jelentős különbségek, azaz élek érintetlenek maradnak. Sebessége nagyban függ az ablakmérettől, elnevezése a kétlépcsős (bilaterális) mivoltából fakad.
Maga a total variation a képen látható változások, vagyis a kép gradienseinek az összege. A zajszűrő módszer célja egy olyan képet alkotni, aminek a TV-je alacsonyabb, miközben nagyon hasonlít az eredeti képhez. Több algoritmus létezik a feladat megoldására, az egyik legnépszerűbb a Chambolle-Pock algoritmus.
A Wavelet-transzformáció hasonló a Fourier-transzformációhoz, de a wavelet lokális információt is megőriz, vagyis nemcsak azt mondja meg, hogy milyen frekvenciák vannak jelen a képen, hanem azt is, hogy ezek hol helyezkednek el. A transzformációt követően az információ komponensekre van bontva, majd egy threshold művelet következik, végül pedig egy inverz Wavelet-transzformáció eredményez olyan képet, ahol az élek megtartásával megszűnt a nem kívánatos zaj. Népszerű módszer képfeldolgozó szoftverekben.
A zajt a szomszédok vizsgálata helyett a kép teljes egészének elemzésével próbálja eltávolítani. Nemcsak a közeli hasonló régiók alapján súlyoz, hanem a kép bármely távolabbi részén található hasonló területeket is alapul veszi. Az NLM számításigényes, de a többi módszerhez képest szebb, használhatóbb eredményt ad.
A sugárkövetés a GPU gyártók (Nvidia, AMD) marketingjének köszönhetően mára már közismert fogalommá vált, azonban a tervezőprogramok, a filmstúdiók által használt szerkesztők és különböző tudományterületek évtizedek óta alkalmazzák. A Ray-tracing (röviden RT) során egy sugár indul el a kamerából, és ha ez a sugár objektummal ütközik, az algoritmus kiszámolja a fényinterakciókat, azaz tükröződést, fénytörést, árnyékot, globális megvilágítást. A végeredményt több millió sugár átlagolásával lehet közelíteni. Az Ray-Tracing egyik hátránya, hogy a véletlenszerű mintákból fakadó statisztikai fluktuáció zajos eredményhez vezet, amelyet szűrni kell. Az Nvidia Optix RT motorját és AI zajszűrőjét például a Pixar és a SolidWorks is alkalmazza.
PyWavelets telepítése: https://pypi.org/project/PyWavelets
Spóra fénykép: Letöltés
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from skimage.filters import median
from skimage.restoration import denoise_bilateral, denoise_tv_chambolle, denoise_wavelet, denoise_nl_means
# Open the image using PIL
image = Image.open("path-to-resources/noisy-items.png").convert("L")
# Convert image to a NumPy array
data = np.array(image, dtype = np.uint8)
# Footprint for the median filter
custom_footprint = np.array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]], dtype = np.uint8)
# Perform denoising using various algorithms
denoised_image_med = median(data, footprint = custom_footprint)
denoised_image_bl = denoise_bilateral(data, sigma_color = 0.05, sigma_spatial = 5)
denoised_image_tv = denoise_tv_chambolle(data, weight = 0.1)
denoised_image_wl = denoise_wavelet(data)
denoised_image_nlm = denoise_nl_means(data, h = 0.1, fast_mode = "True", patch_size = 5, patch_distance = 6)
# Display images
filters = [
("Original Image", data),
("Median filter", denoised_image_med),
("Bilateral filter", denoised_image_bl),
("Total variation", denoised_image_tv),
("Wavelet", denoised_image_wl),
("Non-local means", denoised_image_nlm)
]
fig, axes = plt.subplots(2, 3, figsize=(12, 8))
for ax, (title, img) in zip(axes.ravel(), filters):
ax.imshow(img, cmap="gray")
ax.set_title(title)
ax.axis("off")
plt.tight_layout()
plt.show()