OpenCV 中的模糊濾鏡

Salman Mehmood 2024年2月15日
OpenCV 中的模糊濾鏡

本演示將介紹如何在 OpenCV 中平滑或模糊影象。我們將在本文末尾討論不同型別的模糊濾鏡以及如何使用它們。

在 OpenCV 中使用不同型別的模糊濾鏡

平滑,也稱為模糊,是影象處理中最常用的操作之一。它通常用於去除影象中的噪聲。

我們可以使用多種線性濾波器,因為線性濾波器很容易實現並且相對較快。OpenCV 中有多種濾波器可用,例如,齊次濾波器、高斯濾波器、中值濾波器或雙邊濾波器,我們將逐一介紹。

首先,我們將看到同質濾波器。齊次濾波器很簡單,每個輸出畫素是齊次濾波器中其核鄰居的平均值。

所有畫素都具有相同的權重,這就是它們被稱為同質濾波器的原因。換句話說,核心是我們可以在影象上應用或卷積的形狀。

numpy 建立了這種平方核心。所以在同質濾波器中,核心看起來像這個影象。

Opencv 模糊示例 1

在同質濾波器中,核心 K 等於 1 除以核心的寬度乘以核心的高度。如果我們想使用這個公式使用 5 x 5 的核心,那麼我們將有 K 等於 1 除以 25,我們將有一個 1 的 5 x 5 核心矩陣。

Opencv 模糊示例 2

現在,我們需要使用 filter2D() 或同質過濾器為影象過濾建立這個核心。首先,我們將使用 imread() 方法讀取影象。

IMG = cv2.imread("opencv-logo.jpg")

我們需要將影象從 BGR 轉換為 RGB,因為 matplotlib 讀取 RGB 格式的影象,而 OpenCV 讀取 BGR 格式的影象。

IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

我們需要使用帶有 float32 資料型別的 ones() 方法定義一個 5x5 核心,然後將其除以 25。

K = np.ones((5, 5), np.float32) / 25

現在,我們可以通過輔助定義的核心來定義我們的目標影象。一種稱為 filter2D() 的方法用於同質過濾器。

第一個引數將是源影象,第二個是目標影象的所需深度,第三個是核心。

HMG = cv2.filter2D(IMG, -1, K)

在下一行中,我們正在迭代一個 for 迴圈,我們將通過此迴圈以 1 x 2 格式在 matplotlib 上顯示影象。

for j in range(2):
    plot.subplot(1, 2, j + 1), plot.imshow(IMGS[j], "gray")

完整示例原始碼:

import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("opencv-logo.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)


T = ["Original IMG", "2D Convolution"]
IMGS = [IMG, HMG]

for j in range(2):
    plot.subplot(1, 2, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

我們可以看到角落裡有一點噪點,在這張圖片上應用 2D 卷積後,角落稍微平滑或模糊。這種模糊可以消除或抑制噪聲,因此這是使用 filter2D() 方法模糊影象的一種方法。

Opencv 模糊輸出 1

模糊濾鏡

一維影象可以用低通濾波器或高通濾波器進行濾波。低通濾波器有助於去除影象的噪聲或模糊等,高通濾波器有助於發現影象中的邊緣。

要獲得模糊的影象,你需要使用低通濾波器對影象進行轉換。OpenCV 中提供了各種演算法;第一個演算法是 blur() 方法。

blur() 方法也稱為平均方法,我們將使用它來應用平均演算法來製作模糊影象。該方法有兩個引數:第一個是影象,第二個是核心,即 (5,5)。

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

IMG = cv2.imread("opencv-logo.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))

T = ["Original IMG", "2D Convolution", "Blur"]
IMGS = [IMG, HMG, BL]

for j in range(3):
    plot.subplot(1, 3, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

結果在 2D 卷積和模糊之間看起來或多或少是相同的,因為我們對這兩個函式應用了相同型別的核心。

Opencv 模糊輸出 2

高斯濾波器

我們來看下一個演算法,就是高斯濾波演算法。高斯濾波器只不過是在 x 和 y 方向上使用不同的權重核心。

在輸出中,畫素位於核心的中間,具有更高或更大的權重。權重隨著與鄰域中心的距離而減小。

較小權重的畫素位於側面,較高權重的畫素位於中央。

當我們採用 5x5 核心時,其結果將類似於影象中顯示的結果。

Opencv 模糊示例 3

讓我們看看如何在 OpenCV 中使用 GaussianBlur() 方法。引數和 blur() 方法一樣,所以第一個引數是輸入影象,第二個是我們的核心,第三個是 Sigma X 值。

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

IMG = cv2.imread("eye.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))
GB = cv2.GaussianBlur(IMG, (5, 5), 0)

T = ["Original IMG", "2D Convolution", "Blur", "GaussianBlur"]
IMGS = [IMG, HMG, BL, GB]

for j in range(4):
    plot.subplot(2, 2, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

我們可以觀察到 GaussianBlur() 方法的結果優於其他模糊方法。

看看原始影象,它有太多的噪點。應用 GaussianBlur() 方法後,所有噪聲都將被移除。

所以 GaussianBlur() 方法是專門為去除影象中的高頻噪聲而設計的。

Opencv 模糊輸出 3

中值濾波器

中值濾波器是將每個畫素值替換為其相鄰畫素的中值的東西。medianBlur() 方法在處理帶有椒鹽噪聲的影象時非常有用。

如果你想了解更多關於椒鹽噪聲的資訊,請點選此連結

我們這裡有一個影象;有些畫素失真,有些是白點或白噪聲,有些是可以看到黑噪聲的地方。因為畫素像鹽一樣扭曲,黑色畫素看起來像胡椒,所以稱為椒鹽噪聲。

樣本水影象

讓我們將此影象用作 medianBlur() 方法中的源。源影象將是第一個引數,第二個引數是核心大小。

我們必須注意,核心大小必須是奇數,如 3、5、7 等,除了 1。如果使用 1,它將顯示原始影象。

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

IMG = cv2.imread("water.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))
GB = cv2.GaussianBlur(IMG, (5, 5), 0)
MB = cv2.medianBlur(IMG, 5)

T = ["Original IMG", "2D Convolution", "Blur", "GaussianBlur", "medianBlur"]
IMGS = [IMG, HMG, BL, GB, MB]

for j in range(5):
    plot.subplot(2, 3, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

我們在下面看到使用 medianBlur() 方法獲得的最佳結果。

Opencv 模糊輸出 4

雙邊過濾器

讓我們看看最後一個過濾器,稱為雙邊過濾器。因此,通過使用其他過濾器,我們不僅消除了噪聲,還平滑了邊緣。

有時我們需要保留邊緣,這意味著即使影象模糊,所有邊緣仍保持清晰。

bilateralFilter() 方法將影象作為第一個引數。第二個引數是過濾時使用的每個畫素的直徑,第三個引數是 Sigma 顏色,第四個是 Sigma 空間。

Sigma 顏色是顏色空間中的濾波器 Sigma,Sigma 空間是座標空間中的濾波器 Sigma。

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

IMG = cv2.imread("lena-1.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))
GB = cv2.GaussianBlur(IMG, (5, 5), 0)
MB = cv2.medianBlur(IMG, 5)
BF = cv2.bilateralFilter(IMG, 9, 75, 75)

T = [
    "Original IMG",
    "2D Convolution",
    "Blur",
    "GaussianBlur",
    "medianBlur",
    "bilateralFilter",
]
IMGS = [IMG, HMG, BL, GB, MB, BF]
plot.figure(figsize=(8, 6))
for j in range(6):
    plot.subplot(2, 3, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

看看在應用 bilateralFilter() 方法的地方如何更好地保留邊緣。雙邊濾波器在去除噪聲方面非常有效,同時保持邊緣銳利。

Opencv 模糊輸出 5

作者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

相關文章 - Python OpenCV