SciPy
庫本身是針對科學計算而不是影像處理的,只是影像處理也包含了很多數學計算,
所以Scipy
也提供了一個專門的模組ndimage
用於影像處理。
ndimage
模組提供的功能包括輸入/輸出影像、顯示影像、基本操作(如裁剪、翻轉、旋轉等)、影像過濾(如去噪、銳化等)、影像分割、分類、特徵提取以及註冊/配準等任務。
這個模組支援多種影像格式的讀取和寫入,使得對影像的處理變得方便快捷。
1. 主要功能
雖然影像處理不是Scipy
的主要目的,Scipy
中也提供了70
多個各類影像處理函式。
類別 | 主要函式 | 說明 |
---|---|---|
過濾器 | 包含convolve等20多個函式 | 各類卷積和濾波相關的計算函式 |
傅立葉濾波器 | 包含fourier_ellipsoid等4個函式 | 多維橢球傅立葉,高斯傅立葉等濾波器 |
影像插值 | 包含affine_transform等8個函式 | 影像的反射變換,移動,旋轉等相關函式 |
影像測量 | 包含center_of_mass等將近20個函式 | 計算影像幾何特徵的相關函式 |
形態學 | 包含binary_closing等20多個函式 | 影像的侵蝕,膨脹,二元開閉運算等等 |
影像處理底層函式專業性較強,下面結合圖片演示一些比較直觀的例子。
2. 邊緣檢測
影像邊緣檢測在計算機視覺和影像處理中是非常重要的任務之一。
邊緣是影像中畫素值發生顯著變化的地方,它可以提供有關影像的重要資訊,例如物體的輪廓、邊界等。
ndimage
模組中提供了多種演算法來檢測邊緣,下面演示三種不同的邊緣檢測演算法的效果:
(示例中所用的圖片是維基百科上找的一個python logo
)
2.1. sobel演算法
import matplotlib.pyplot as plt
import cv2
from scipy import ndimage
image = plt.imread("d:/share/python-logo.png")
# 影像灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用索貝爾邊緣檢測演算法
name = "sobel"
edges = ndimage.sobel(gray)
# 顯示原始影像和邊緣檢測結果
fig, ax = plt.subplots(1, 3, figsize=(8, 4))
ax[0].imshow(image)
ax[0].set_title("原始影像")
ax[1].imshow(gray, cmap="gray")
ax[1].set_title("灰度影像")
ax[2].imshow(edges, cmap="gray")
ax[2].set_title("邊緣檢測({}演算法)".format(name))
plt.show()
2.2. prewitt演算法
程式碼和上面的類似,不同的部分就下面兩行。
# 使用prewitt邊緣檢測演算法
name = "prewitt"
edges = ndimage.prewitt(gray)
2.3. laplace演算法
上面兩種演算法的效果看上去很類似,laplace
演算法的結果看上去比上面兩種效果更好一些。
name = "laplace"
edges = ndimage.laplace(gray)
3. 侵蝕和膨脹
侵蝕和膨脹是最基本的兩種影像形態學操作,它們的作用用來增強目標特徵。
仍然使用上面的python logo
圖片,演示侵蝕和膨脹的操作。
import matplotlib.pyplot as plt
import cv2
from scipy import ndimage
image = plt.imread("d:/share/python-logo.png")
# 影像灰度化
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 影像侵蝕
structure = ndimage.generate_binary_structure(2, 2)
erosion = ndimage.binary_erosion(image, structure)
# 影像膨脹
dilation = ndimage.binary_dilation(image, structure)
# 顯示原始影像、侵蝕影像和膨脹影像
fig, ax = plt.subplots(1, 3, figsize=(8, 4))
ax[0].imshow(image, cmap="gray")
ax[0].set_title("灰度影像")
ax[1].imshow(erosion, cmap="gray")
ax[1].set_title("影像--侵蝕")
ax[2].imshow(dilation, cmap="gray")
ax[2].set_title("影像--膨脹")
plt.show()
簡單來說,侵蝕操作會擴張影像中黑色的區域,反之,膨脹操作會擴張影像中白色的區域。
直觀上來看的話,侵蝕變瘦了,膨脹變胖了。
4. 總結
Scipy
的影像模組本質上是把影像當作陣列來處理,
雖然它不是專門的影像處理庫,不過它處理速度很快,且和numpy
等庫結合緊密,
經常處理影像的朋友可以把它當成一個輔助的工具。