iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
Software Development

從像素到 Computer Vision:30 天理解數位影像處理系列 第 14

Day 14 | Prewitt Operator:它和 Sobel 到底差在哪裡?

  • 分享至 

  • xImage
  •  

上一篇介紹了 Sobel Operator。

它利用兩組 Kernel,分別計算 X 和 Y 方向的亮度變化,再找出圖片中可能存在邊緣的位置。

在影像處理中,其實還有一個跟 Sobel Operator 長得很像的名詞:Prewitt Operator。

可是不是已經有 Sobel Operator 了嗎,幹嘛還要 Prewitt Operator?

先看看兩個 Kernel

Sobel 的 X 方向 Kernel。

-1  0  1
-2  0  2
-1  0  1

Prewitt 的 X 方向 Kernel。

-1  0  1
-1  0  1
-1  0  1

如果換成 Y 方向。

Sobel。

-1 -2 -1
 0  0  0
 1  2  1

Prewitt。

-1 -1 -1
 0  0  0
 1  1  1

看起來是不是只差了一個數字?

沒錯,這兩個最大的差別就在於:

Sobel 把中心那一列(或那一欄)的權重加大了。

為什麼這樣?

上一篇提到,Sobel 認為距離中心最近的 Pixel 通常比較具有代表性。

因此,它把中間那一列(或那一欄)的權重提高,讓附近 Pixel 的影響力更大。

Prewitt 則沒有這樣做,它把三列(或三欄)都視為同樣重要。

因此,每個方向的權重都完全一致。

那誰比較好?

如果只是計算亮度變化,兩者其實都可以。

但是,Sobel 因為增加了中心權重,通常會比 Prewitt 對雜訊更不敏感。

因此實際應用中,大部分情況都會優先使用 Sobel。

這也是為什麼很多影像處理函式庫都有 Sobel,卻不一定提供 Prewitt。

實作:自己建立 Prewitt Kernel

OpenCV 並沒有提供專門的 Prewitt 函式。

不過因為我們之前介紹過 Convolution,所以只需要自己建立 Kernel。

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

img = cv2.imread("dog.jpeg", cv2.IMREAD_GRAYSCALE)

kernel_x = np.array([
    [-1, 0, 1],
    [-1, 0, 1],
    [-1, 0, 1]
], dtype=np.float32)

kernel_y = np.array([
    [-1, -1, -1],
    [ 0,  0,  0],
    [ 1,  1,  1]
], dtype=np.float32)

grad_x = cv2.filter2D(img, cv2.CV_32F, kernel_x)
grad_y = cv2.filter2D(img, cv2.CV_32F, kernel_y)

接著把兩個方向合成。

magnitude = cv2.magnitude(grad_x, grad_y)

plt.imshow(magnitude, cmap="gray")
plt.title("Prewitt")
plt.axis("off")
plt.show()

結果:

https://ithelp.ithome.com.tw/upload/images/20260831/201817809Cf3xqiJsQ.png

如果再和 Sobel 的結果放在一起比較,應該會發現兩張圖片非常接近。

Prewitt 和 Sobel 的比較

項目 Prewitt Sobel
中心權重 沒有
對雜訊的抵抗能力 普通 較佳
計算方式 簡單 稍微複雜
實際使用 較少 非常常見

因此,現在大多時候介紹 Gradient 時都會以 Sobel 作為主要例子。

那為什麼還要學 Prewitt?

Prewitt 的價值,不是在於它比 Sobel 更好。

而是在於它讓我們理解:

Gradient Kernel 並沒有唯一答案。

只要符合「比較不同方向亮度變化」的設計理念,就能設計出不同的 Kernel。

Sobel 和 Prewitt,只是其中兩個經典例子。

真正重要的,是知道這些 Kernel 都是在估計亮度變化。

今天總結

今天介紹了 Prewitt Operator。

它和 Sobel 一樣,都利用 Convolution 計算圖片在不同方向上的 Gradient。

最大的差別在於 Prewitt 對所有鄰近 Pixel 給予相同權重。

而 Sobel 則提高了中心 Pixel 附近的影響力,因此通常對雜訊更有抵抗能力。

到了這裡,我們已經學會利用一階微分的概念來找亮度變化。

但如果不是觀察亮度「變得有多快」,而是觀察亮度「變化是否突然改變」呢?

下一篇,我們就來介紹另一種完全不同的思路:

Laplacian(拉普拉斯算子)


上一篇
Day 13 | Sobel Operator:如何找出圖片的亮度變化?
下一篇
Day 15 | Laplacian:除了亮度變化,還能觀察什麼?
系列文
從像素到 Computer Vision:30 天理解數位影像處理25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言