2024-09-29|閱讀時間 ‧ 約 12 分鐘

[OpenCV][Python]fastNlMeansDenoising非局部均值濾波

cv2.fastNlMeansDenoising() 是 OpenCV 中一個非常有效的去噪函數,基於非局部均值濾波算法(Non-Local Means Filtering)。它能夠有效地去除圖像中的隨機噪聲(如高斯噪聲),並保留圖像的細節,特別適合處理含有隨機噪聲的圖像。

這個函數的主要特點是能夠根據像素周圍的鄰域進行濾波,而不僅僅依賴局部的像素值,因此可以在去除噪聲的同時,保留圖像的細節

fastNlMeansDenoising結果圖


調用方式

cv2.fastNlMeansDenoising() 函數的使用格式如下:

cv2.fastNlMeansDenoising(src, dst=None, h=3, templateWindowSize=7, searchWindowSize=21)
  • src: 輸入的單通道圖像(灰度圖像)。
  • dst: 輸出的圖像(可以設為 None,表示輸出結果覆蓋原圖)。
  • h: 決定去噪的強度,值越高去噪越強,但可能會丟失更多細節。
  • templateWindowSize: 鄰域大小,通常設為奇數(默認為 7)。
  • searchWindowSize: 檢索窗口大小,越大會增加計算量,但效果更好(默認為 21)。

實作範例程式碼

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

# 讀取原始圖像
img = cv2.imread('lena.png', 0) # 讀取灰度圖像

# 添加高斯噪聲到圖像
noise = np.random.normal(0, 25, img.shape).astype(np.uint8) # 創建高斯噪聲
noisy_img = cv2.add(img, noise) # 將噪聲加入到原始圖像

# 使用fastNlMeansDenoising進行去噪
denoised_img = cv2.fastNlMeansDenoising(noisy_img, None, h=10, templateWindowSize=7, searchWindowSize=21)

# 顯示結果
plt.figure(figsize=(12, 6))

# 顯示原始圖像
plt.subplot(1, 3, 1)
plt.imshow(img, cmap='gray')
plt.title("原始圖像")
plt.axis('off')

# 顯示加噪聲的圖像
plt.subplot(1, 3, 2)
plt.imshow(noisy_img, cmap='gray')
plt.title("加噪聲圖像")
plt.axis('off')

# 顯示去噪後的圖像
plt.subplot(1, 3, 3)
plt.imshow(denoised_img, cmap='gray')
plt.title("去噪後圖像")
plt.axis('off')

plt.show()

結果分析

  • 原始圖像:這是最初沒有任何噪聲的圖像。
  • 加噪聲圖像:在原始圖像上添加了隨機的高斯噪聲,這種噪聲在拍攝過程中可能因為感光元件的問題產生,導致圖像質量下降。
  • 去噪後圖像:通過 cv2.fastNlMeansDenoising() 去除了隨機噪聲,保留了圖像的大部分細節。


參數說明

  • h(強度參數):這個參數控制去噪的強度,較大的值會去掉更多的噪聲,但可能會損失更多細節。如果你的圖像噪聲較少,推薦設置較小的 h 值。
  • templateWindowSize:這是計算非局部均值時的模板窗口大小,通常設為奇數,值越大對結果的影響也越大。
  • searchWindowSize:這個窗口決定了在模板窗口之外搜尋類似區域的範圍。較大的搜尋窗口通常能夠產生更好的結果,但運行速度會變慢。


與其他濾波器比較

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

# 讀取原始圖像
img = cv2.imread('輸入圖像', 0) # 讀取灰度圖像

# kernel 調整
kernel = 11
# 添加高斯噪聲到圖像
noise = np.random.normal(0, 25, img.shape).astype(np.uint8) # 創建高斯噪聲
noisy_img = cv2.add(img, noise) # 將噪聲加入到原始圖像

# 1. 使用fastNlMeansDenoising進行去噪
denoised_img_nlmeans = cv2.fastNlMeansDenoising(noisy_img, None, h=45, templateWindowSize=9, searchWindowSize=21)

# 2. 使用均值濾波進行去噪
denoised_img_mean = cv2.blur(noisy_img, (kernel, kernel))

# 3. 使用高斯濾波進行去噪
denoised_img_gaussian = cv2.GaussianBlur(noisy_img, (kernel, kernel), 0)

# 4. 使用中值濾波進行去噪
denoised_img_median = cv2.medianBlur(noisy_img, kernel)

# 5. 使用雙邊濾波進行去噪
denoised_img_bilateral = cv2.bilateralFilter(noisy_img, 9, 75, 75)

# 顯示結果
plt.figure(figsize=(18, 12))

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 中文字體
plt.rcParams['axes.unicode_minus'] = False # 解決座標軸負號顯示問題

# 顯示加噪聲的圖像
plt.subplot(2, 3, 1)
plt.imshow(noisy_img, cmap='gray')
plt.title("加噪聲圖像")
plt.axis('off')

# 顯示fastNlMeansDenoising的去噪結果
plt.subplot(2, 3, 2)
plt.imshow(denoised_img_nlmeans, cmap='gray')
plt.title("非局部均值去噪")
plt.axis('off')

# 顯示均值濾波去噪結果
plt.subplot(2, 3, 3)
plt.imshow(denoised_img_mean, cmap='gray')
plt.title("均值濾波去噪")
plt.axis('off')

# 顯示高斯濾波去噪結果
plt.subplot(2, 3, 4)
plt.imshow(denoised_img_gaussian, cmap='gray')
plt.title("高斯濾波去噪")
plt.axis('off')

# 顯示中值濾波去噪結果
plt.subplot(2, 3, 5)
plt.imshow(denoised_img_median, cmap='gray')
plt.title("中值濾波去噪")
plt.axis('off')

# 顯示雙邊濾波去噪結果
plt.subplot(2, 3, 6)
plt.imshow(denoised_img_bilateral, cmap='gray')
plt.title("雙邊濾波去噪")
plt.axis('off')

plt.tight_layout()
plt.show()


比較結果圖


總結

1. 均值濾波 (Mean Filtering)

  • 原理:均值濾波是一種線性濾波器,將窗口內的像素值取平均,並將該平均值賦予窗口中心的像素點。
  • 適用場景
    • 適合處理輕度隨機噪聲。
    • 對於圖像邊緣保護能力較弱,會導致圖像模糊。
    • 常用於需要快速消除輕微噪聲的場景,如數據預處理、平滑圖像。
  • 缺點:會模糊邊緣和細節,特別不適合應用於邊緣敏感的圖像。

2. 高斯濾波 (Gaussian Filtering)

  • 原理:高斯濾波對像素周圍的鄰域加權平均,權重由距離像素的高斯分佈決定。距離中心越近的像素權重大。
  • 適用場景
    • 適合處理高斯噪聲(如感光器產生的隨機噪聲)。
    • 用於影像去噪的同時需要保持一定的平滑度。
    • 經常用於圖像模糊處理、邊緣檢測前的平滑。
  • 缺點:雖然保留了更多的圖像細節,但仍然可能造成邊緣模糊。

3. 中值濾波 (Median Filtering)

  • 原理:中值濾波是一種非線性濾波方法,對窗口內的像素進行排序,並將中值賦予窗口中心的像素點。
  • 適用場景
    • 非常適合處理椒鹽噪聲(Salt-and-Pepper Noise)。
    • 用於需要去除孤立噪聲點的情況,且在保護圖像邊緣方面表現良好。
    • 適用於圖像處理中的許多場合,如醫學圖像處理和衛星圖像去噪。
  • 缺點:對於大範圍的隨機噪聲效果不如高斯濾波或其他方法,且處理速度相對較慢。

4. 雙邊濾波 (Bilateral Filtering)

  • 原理:雙邊濾波結合空間鄰域的距離與像素值的差異來進行加權平均,從而在去除噪聲的同時保留邊緣。
  • 適用場景
    • 適合需要去除噪聲但同時保留圖像邊緣和細節的場景,如照片去噪、精細影像處理等。
    • 常用於去噪與保持邊緣的平衡場景,如人像照片後期處理。
  • 缺點:計算量較大,處理速度慢,不適合實時應用。

5. 非局部均值去噪 (Non-Local Means Denoising)

  • 原理:基於圖像的自相似性,搜尋圖像的各個區域中相似的區塊進行加權平均。這使得它在保留細節的同時能很好地去除噪聲。
  • 適用場景
    • 適合處理高斯噪聲和隨機噪聲,特別是在需要保留圖像細節的情況下,如高質量照片和影像處理。
    • 在醫學影像處理、顯微圖像處理、攝影後期等細節要求高的場景中使用。
  • 缺點:運行速度慢,適用於非實時的去噪應用。



分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.