蒲瑞维特算子

蒲瑞维特算子（英語：Prewitt Operator）是一種在影像處理中，用於邊緣檢測的離散微分運算子。此算子由Judith M. S. Prewitt發明，並以她的名字命名。蒲瑞维特算子通過在水平方向和垂直方向上對影像進行捲積，使用一個小型的整數值濾波器來完成運算，因此在計算成本方面相對較低，類似於索伯算子。蒲瑞维特算子的優點在於其計算簡單且效率高，適合於需要快速邊緣檢測的應用場景。 然而，其粗糙的梯度近似使得它在處理細節豐富或高頻率變化較多的影像時效果不佳。為了更準確地檢測邊緣，通常需要使用如坎尼算子等更先進的方法。 蒲瑞维特算子包含兩個3x3的矩陣，分別為水平方向以及垂直方向，表示為 M x {\displaystyle M_{x}} 與 M y {\displaystyle M_{y}} 。 M x = [ + 1 + 1 + 1 0 0 0 − 1 − 1 − 1 ] and M y = [ + 1 0 − 1 + 1 0 − 1 + 1 0 − 1 ] {\displaystyle \mathbf {M_{x}} ={\begin{bmatrix}+1&+1&+1\\0&0&0\\-1&-1&-1\end{bmatrix}}\quad {\mbox{and}}\quad \mathbf {M_{y}} ={\begin{bmatrix}+1&0&-1\\+1&0&-1\\+1&0&-1\end{bmatrix}}} 利用上述兩矩陣與影像做2d卷積運算，即可達到水平向與垂直向差分的效果，得到其對應亮度梯度向量，公式如下： G x = M x ∗ A and G y = M y ∗ A {\displaystyle \mathbf {G_{x}} =\mathbf {M_{x}} *\mathbf {A} \quad {\mbox{and}}\quad \mathbf {G_{y}} =\mathbf {M_{y}} *\mathbf {A} } 在這裏運算子'*'代表的2d卷積運算，A代表的是原影像。 對於影像中每個點的梯度值，透過以下公式得到： G = G x 2 + G y 2 {\displaystyle \mathbf {G} ={\sqrt {{\mathbf {G} _{x}}^{2}+{\mathbf {G} _{y}}^{2}}}} 運用 G x {\displaystyle G_{x}} 與 G y {\displaystyle G_{y}} ，可以計算其梯度向量： Θ = atan2 ⁡ ( G y , G x ) {\displaystyle \mathbf {\Theta } =\operatorname {atan2} \left({\mathbf {G} _{y},\mathbf {G} _{x}}\right)} 在實作上，因為只有該點的周圍八個點需要被計算，同時在梯度向量的計算上也都只牽涉到整數的加法計算，而且上述的兩個離散濾波器是可分解的： M x = [ + 1 + 1 + 1 0 0 0 − 1 − 1 − 1 ] = [ + 1 0 − 1 ] [ + 1 + 1 + 1 ] {\displaystyle \mathbf {M_{x}} ={\begin{bmatrix}+1&+1&+1\\0&0&0\\-1&-1&-1\end{bmatrix}}={\begin{bmatrix}+1\\0\\-1\end{bmatrix}}{\begin{bmatrix}+1&+1&+1\end{bmatrix}}} M y = [ + 1 0 − 1 + 1 0 − 1 + 1 0 − 1 ] = [ + 1 + 1 + 1 ] [ + 1 0 − 1 ] {\displaystyle \mathbf {M_{y}} ={\begin{bmatrix}+1&0&-1\\+1&0&-1\\+1&0&-1\end{bmatrix}}={\begin{bmatrix}+1\\+1\\+1\end{bmatrix}}{\begin{bmatrix}+1&0&-1\end{bmatrix}}} # Read image and convert it into grayscale img_file = '<name of input image file>.<file format>' img = np.array(Image.open(img_file).convert('L')) # Prepare edge, horizontal edge and vertical edge image arrays edge_img = np.zeros_like(img) horizontal_edge_img = np.zeros_like(img) vertical_edge_img = np.zeros_like(img) # Prewitt operator matrices Mx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]]) My = np.array([[1, 0, -1], [1, 0, -1], [1, 0, -1]]) # Perform 2d convolution for i in range(1, img.shape[0]-1): for j in range(1, img.shape[1]-1): A = img[i-1:i+2, j-1:j+2] Gx = np.sum(Mx * A) Gy = np.sum(My * A) horizontal_edge_img[i][j] = abs(Gx) vertical_edge_img[i][j] = abs(Gy) edge_img[i][j] = np.sqrt(Gx ** 2 + Gy ** 2) # Define a threshold value thresholdValue = 80 edge_img = np.where(edge_img < thresholdValue, 0, edge_img) horizontal_edge_img = np.where(horizontal_edge_img < thresholdValue, 0, horizontal_edge_img) vertical_edge_img = np.where(vertical_edge_img < thresholdValue, 0, vertical_edge_img) plt.figure() plt.subplot(221) plt.axis('off'); plt.title('Grayscale image of fruits'); plt.imshow(img, cmap='gray', vmin=0, vmax=255) plt.subplot(222) plt.axis('off') plt.title('Horizontal edge') plt.imshow(horizontal_edge_img, cmap='gray', vmin=0, vmax=255) plt.subplot(223) plt.axis('off') plt.title('Vertical edge') plt.imshow(vertical_edge_img, cmap='gray', vmin=0, vmax=255) plt.subplot(224) plt.axis('off') plt.title('Edge image') plt.imshow(edge_img, cmap='gray', vmin=0, vmax=255) plt.show() 索伯算子 坎尼算子 邊緣偵測 特徵偵測 數位影像處理 影像處理 電腦視覺 數位訊號處理 Prewitt, J.M.S. Object Enhancement and Extraction. Picture processing and Psychopictorics. Academic Press. 1970.