iT邦幫忙

2025 iThome 鐵人賽

DAY 4
0

在數位影像的世界裡,影像雜訊是無可避免的問題。無論是來自於光線不足、感光元件的熱雜訊,或是傳輸過程中的失真,雜訊都會降低影像品質。本篇將介紹常見的影像雜訊類型,以及如何使用濾波(filtering)技術來去除或平滑這些雜訊,從而提升影像的品質。

圖片雜訊

影像雜訊是指在影像中出現的不期望的、隨機的像素值變化。根據其產生原因和特性,雜訊可以有多種形式,這邊僅介紹圖像處理中常見的兩種。

椒鹽雜訊

椒鹽雜訊,顧名思義,就像在圖片上撒了一把白色(鹽)和黑色(胡椒)的顆粒。它表現為影像中隨機出現的純白或純黑的像素點。成因通常是由於影像感測器中的壞點、類比數位轉換過程中的錯誤,或數據傳輸錯誤所導致。

高斯雜訊

高斯雜訊是另一種非常普遍的雜訊,它的強度變化遵循常態分佈。這意味著每個像素的強度都在其原始值的基礎上,隨機增加或減少了一個符合常態分佈的微小量。成因主要是感光元件在低光照或高溫環境下產生的電子雜訊。

濾波

要對抗雜訊,最主要的方法就是「濾波」。濾波的本質,是透過一個稱為濾波核 (kernel) 或濾波器的小型矩陣,在影像上滑動,並根據核內的權重和鄰近像素的值,來重新計算中心像素的新值。這個過程可以平滑影像、去除雜訊,甚至增強邊緣。

型態學處理

在介紹主流濾波方法前,我們先快速認識一下型態學處理。這是一系列基於「形狀」的非線性操作,常用於二值化影像。其中最基礎的是侵蝕 (erosion) 和膨脹 (dilation)。

  • 侵蝕:會「侵蝕」掉物體(通常是白色部分)的邊界。其效果是讓物體變小,可以有效去除小的白色噪點(鹽點)。

  • 膨脹:會「擴張」物體的邊界,讓物體變大。可以用來填補物體內部的小黑洞(胡椒點)。

卷積

卷積 (convolution) 是線性濾波的核心數學運算。可以想像我們拿著一個小的「濾鏡」,覆蓋在影像的某個區域上,然後將濾鏡上的每個數值與其對應的影像像素值相乘,最後將所有乘積加總,得到的值就是這個區域中心點的新像素值。

盒式濾波

盒式濾波是最簡單的線性濾波器,也稱為均值濾波 (averaging filter)。它的濾波核中所有元素的值都相等(通常是1),最後再除以元素的總數。

例如,一個 3x3 的盒式濾波核就是:

https://ithelp.ithome.com.tw/upload/images/20250814/20178100T3LClisjoJ.png

它的效果就是將中心像素的值,替換為其鄰近區域內所有像素的平均值。這會讓影像變得平滑模糊,但效果比較生硬,容易產生一些不自然的邊緣。

高斯濾波

高斯濾波是一種更精緻的線性濾波。它的濾波核權重不是平均分配的,而是根據高斯分佈來生成。這意味著,距離中心點越近的像素,會被賦予越高的權重。

高斯濾波主要的參數是標準差 sigma,當 sigma 越大,模糊效果越強。

相對於盒式濾波,高斯濾波處理結果更自然,也常用於處理高斯雜訊。

中值濾波

與前面兩者不同,中值濾波是一種非線性濾波。它的運作方式非常直觀:

  1. 用一個滑動窗口(濾波核)掃過影像。

  2. 讀取窗口內所有的像素值。

  3. 對這些像素值進行排序。

  4. 用排序後的中位數 (median) 來取代中心像素的值。

因為是取中位數,中值濾波不太受椒鹽雜訊這種離群值影響,因此很適合用於這方面的處理。

雜訊與捲積效果比較

import cv2
import numpy as np
import matplotlib.pyplot as plt

# --- Step 0: 定義圖片顯示函式 ---
def show_images(images, titles):
    plt.figure(figsize=(15, 10))
    for i, (image, title) in enumerate(zip(images, titles)):
        plt.subplot(2, 3, i + 1)
        plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
        plt.title(title)
        plt.axis('off')
    plt.tight_layout()
    plt.show()

# --- Step 1: 讀取圖片並定義雜訊函式 ---
# 為了方便,我們直接使用灰階影像來觀察
img = np.fromfunction(lambda y, x: x + y, (256, 256), dtype=np.uint8)

def add_salt_and_pepper_noise(image, amount=0.05):
    """ 為圖片添加椒鹽雜訊 """
    noisy_img = image.copy()
    num_salt = np.ceil(amount * image.size * 0.5)
    coords = [np.random.randint(0, i - 1, int(num_salt)) for i in image.shape]
    noisy_img[coords[0], coords[1]] = 255

    num_pepper = np.ceil(amount * image.size * 0.5)
    coords = [np.random.randint(0, i - 1, int(num_pepper)) for i in image.shape]
    noisy_img[coords[0], coords[1]] = 0
    return noisy_img

def add_gaussian_noise(image, mean=0, sigma=25):
    """ 為圖片添加高斯雜訊 """
    row, col = image.shape
    gauss = np.random.normal(mean, sigma, (row, col))
    noisy_img = image + gauss
    # 將像素值限制在 0-255 範圍內
    noisy_img = np.clip(noisy_img, 0, 255)
    return noisy_img.astype(np.uint8)

# --- Step 2: 產生帶有雜訊的影像 ---
sp_noise_img = add_salt_and_pepper_noise(img)
gaussian_noise_img = add_gaussian_noise(img)

# 將灰階轉回 BGR 以便顯示
original_bgr = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
sp_noise_bgr = cv2.cvtColor(sp_noise_img, cv2.COLOR_GRAY2BGR)
gaussian_noise_bgr = cv2.cvtColor(gaussian_noise_img, cv2.COLOR_GRAY2BGR)

# 顯示原始影像和兩種雜訊影像
print("--- 原始影像與兩種雜訊 ---")
show_images([original_bgr, sp_noise_bgr, gaussian_noise_bgr],
            ['Original', 'Salt & Pepper Noise', 'Gaussian Noise'])

# --- Step 3: 應用濾波器 ---
# 使用 5x5 的濾波核
kernel_size = 5

# 對椒鹽雜訊影像進行濾波
sp_gaussian_filtered = cv2.GaussianBlur(sp_noise_img, (kernel_size, kernel_size), 0)
sp_median_filtered = cv2.medianBlur(sp_noise_img, kernel_size)

# 對高斯雜訊影像進行濾波
gs_gaussian_filtered = cv2.GaussianBlur(gaussian_noise_img, (kernel_size, kernel_size), 0)
gs_median_filtered = cv2.medianBlur(gaussian_noise_img, kernel_size)

# --- Step 4: 顯示與比較結果 ---
print("\n--- 處理椒鹽雜訊 ---")
show_images([sp_noise_bgr, cv2.cvtColor(sp_gaussian_filtered, cv2.COLOR_GRAY2BGR), cv2.cvtColor(sp_median_filtered, cv2.COLOR_GRAY2BGR)],
            ['Salt & Pepper Noise', 'Gaussian Filtered', 'Median Filtered'])

print("\n--- 處理高斯雜訊 ---")
show_images([gaussian_noise_bgr, cv2.cvtColor(gs_gaussian_filtered, cv2.COLOR_GRAY2BGR), cv2.cvtColor(gs_median_filtered, cv2.COLOR_GRAY2BGR)],
            ['Gaussian Noise', 'Gaussian Filtered', 'Median Filtered'])

https://ithelp.ithome.com.tw/upload/images/20250814/20178100t4kDWevfVK.pnghttps://ithelp.ithome.com.tw/upload/images/20250814/20178100HiHK6w0be7.pnghttps://ithelp.ithome.com.tw/upload/images/20250814/20178100ksxuapWNAt.png


上一篇
Day 3 - 曝光與直方圖
下一篇
Day 5 - 特徵工程(一) 影像的關鍵點
系列文
從0開始:傳統圖像處理到深度學習模型23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言