一. Prewitt濾波器簡介
Prewitt是一種常用的檢測圖像邊緣的濾波器,它分為橫向和縱向算子,分別用於檢測縱向和橫向的邊緣(注意:橫向形式的濾波器檢測圖像的縱向邊緣,縱向形式的濾波器檢測圖像的橫向邊緣)。

橫向Prewitt濾波器(檢測縱向邊緣) ↑

縱向Prewitt濾波器(檢測橫向邊緣) ↑
二. Prewitt濾波器和Sobel濾波器比較
注意比較記憶 Prewitt 濾波器和 Sobel 濾波器,它們在形式和功能上十分相近,Sobel濾波器的算子如下兩圖:

Sobel 縱向算子,提取圖像橫向邊緣 ↑

Sobel 橫向算子,提取圖像縱向邊緣 ↑
三. 實驗:實現 Prewitt 算子並用算子對圖像進行邊緣檢測
1 import cv2 2 3 import numpy as np 4 5 # prewitt filter 6 7 def prewitt_filter(img, K_size=3): 8 9 H, W = img.shape 10 11 # Zero padding 12 13 pad = K_size // 2 14 15 out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float) 16 17 out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float) 18 19 tmp = out.copy() 20 21 out_v = out.copy() 22 23 out_h = out.copy() 24 25 ## prewitt vertical kernel 26 27 Kv = [[-1., -1., -1.],[0., 0., 0.], [1., 1., 1.]] 28 29 ## prewitt horizontal kernel 30 31 Kh = [[-1., 0., 1.],[-1., 0., 1.],[-1., 0., 1.]] 32 33 # filtering 34 35 for y in range(H): 36 37 for x in range(W): 38 39 out_v[pad + y, pad + x] = np.sum(Kv * (tmp[y: y + K_size, x: x + K_size])) 40 41 out_h[pad + y, pad + x] = np.sum(Kh * (tmp[y: y + K_size, x: x + K_size])) 42 43 out_v = np.clip(out_v, 0, 255) 44 45 out_h = np.clip(out_h, 0, 255) 46 47 out_v = out_v[pad: pad + H, pad: pad + W].astype(np.uint8) 48 49 out_h = out_h[pad: pad + H, pad: pad + W].astype(np.uint8) 50 51 return out_v, out_h 52 53 # Read Gray image 54 55 img = cv2.imread("../paojie_g.jpg",0).astype(np.float) 56 57 # prewitt filtering 58 59 out_v, out_h = prewitt_filter(img, K_size=3) 60 61 # Save result 62 63 cv2.imwrite("out_v.jpg", out_v) 64 65 cv2.imshow("result_v", out_v) 66 67 cv2.imwrite("out_h.jpg", out_h) 68 69 cv2.imshow("result_h", out_h) 70 71 cv2.waitKey(0) 72 73 cv2.destroyAllWindows()
四. 實驗結果:

原圖 ↑

Prewitt 橫向算子濾波結果(過濾得到縱向邊緣) ↑

Prewitt 縱向算子濾波結果(過濾得到橫向邊緣) ↑
我同時用同樣大小的 Sobel算子 對同樣圖像進行了邊緣檢測,結果如下:

Sobel 橫向算子濾波結果(過濾得到縱向邊緣) ↑

Sobel 縱向算子濾波結果(過濾得到橫向邊緣) ↑
從實驗結果,我們可以觀察到,對比使用 Sobel算子 和 Prewitt算子 進行圖像邊緣檢測 ,Sobel濾波器能夠獲得更加清晰明亮的邊緣。
五. 參考內容: