OpenCV 中的模糊濾鏡
本演示將介紹如何在 OpenCV 中平滑或模糊影象。我們將在本文末尾討論不同型別的模糊濾鏡以及如何使用它們。
在 OpenCV 中使用不同型別的模糊濾鏡
平滑,也稱為模糊,是影象處理中最常用的操作之一。它通常用於去除影象中的噪聲。
我們可以使用多種線性濾波器,因為線性濾波器很容易實現並且相對較快。OpenCV 中有多種濾波器可用,例如,齊次濾波器、高斯濾波器、中值濾波器或雙邊濾波器,我們將逐一介紹。
首先,我們將看到同質濾波器。齊次濾波器很簡單,每個輸出畫素是齊次濾波器中其核鄰居的平均值。
所有畫素都具有相同的權重,這就是它們被稱為同質濾波器的原因。換句話說,核心是我們可以在影象上應用或卷積的形狀。
numpy 建立了這種平方核心。所以在同質濾波器中,核心看起來像這個影象。
在同質濾波器中,核心 K 等於 1 除以核心的寬度乘以核心的高度。如果我們想使用這個公式使用 5 x 5 的核心,那麼我們將有 K 等於 1 除以 25,我們將有一個 1 的 5 x 5 核心矩陣。
現在,我們需要使用 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 中提供了各種演算法;第一個演算法是 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 卷積和模糊之間看起來或多或少是相同的,因為我們對這兩個函式應用了相同型別的核心。
高斯濾波器
我們來看下一個演算法,就是高斯濾波演算法。高斯濾波器只不過是在 x 和 y 方向上使用不同的權重核心。
在輸出中,畫素位於核心的中間,具有更高或更大的權重。權重隨著與鄰域中心的距離而減小。
較小權重的畫素位於側面,較高權重的畫素位於中央。
當我們採用 5x5 核心時,其結果將類似於影象中顯示的結果。
讓我們看看如何在 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()
方法是專門為去除影象中的高頻噪聲而設計的。
中值濾波器
中值濾波器是將每個畫素值替換為其相鄰畫素的中值的東西。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()
方法獲得的最佳結果。
雙邊過濾器
讓我們看看最後一個過濾器,稱為雙邊過濾器。因此,通過使用其他過濾器,我們不僅消除了噪聲,還平滑了邊緣。
有時我們需要保留邊緣,這意味著即使影象模糊,所有邊緣仍保持清晰。
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()
方法的地方如何更好地保留邊緣。雙邊濾波器在去除噪聲方面非常有效,同時保持邊緣銳利。
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