您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關使用Python怎么對圖像進行膨脹與腐蝕處理,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
讓我們開始吧,同樣我們需要導入必需的庫。
import numpy as np import matplotlib.pyplot as plt from skimage.io import imread, imshow from skimage.draw import circle from skimage.morphology import erosion, dilation
首先讓我們創建一個容易操作的形狀--一個簡單的圓。
circ_image = np.zeros((100, 100)) circ_image[circle(50, 50, 25)] = 1 imshow(circ_image);
現在讓我們定義一個內核。
cross = np.array([[0,1,0], [1,1,1], [0,1,0]]) imshow(cross, cmap = 'gray');
將腐蝕函數應用到創建的圓上。
eroded_circle = erosion(circ_image, cross) imshow(eroded_circle);
圖像看起來幾乎一模一樣。要看到那些微小的差異,我們必須仔細查看圖像。
linecolor = 'red' fig, ax = plt.subplots(1, 2, figsize=(12, 5)) ax[0].imshow(circ_image, cmap = 'gray'); ax[0].set_title('Original', fontsize = 19) ax[0].axvline(x = 25, color = linecolor) ax[0].axvline(x = 75, color = linecolor) ax[0].axhline(y = 25, color = linecolor) ax[0].axhline(y = 75, color = linecolor) ax[1].imshow(eroded_circle, cmap = 'gray'); ax[1].set_title('Eroded', fontsize = 19) ax[1].axvline(x = 25, color = linecolor) ax[1].axvline(x = 75, color = linecolor) ax[1].axhline(y = 25, color = linecolor) ax[1].axhline(y = 75, color = linecolor) fig.tight_layout()
我們可以看到,被腐蝕的圓已經略微縮小了。這就是腐蝕一個對象的意義。如果我們對腐蝕函數進行迭代,它的效果會變得非常明顯。
def multi_erosion(image, kernel, iterations): for i in range(iterations): image = erosion(image, kernel) return image ites = [2,4,6,8,10,12,14,16,18,20] fig, ax = plt.subplots(2, 5, figsize=(17, 5)) for n, ax in enumerate(ax.flatten()): ax.set_title(f'Iterations : {ites[n]}', fontsize = 16) new_circle = multi_erosion(circ_image, cross, ites[n]) ax.imshow(new_circle, cmap = 'gray'); ax.axis('off') fig.tight_layout()
上圖清楚地顯示了圖像是如何被腐蝕的。現在讓我們嘗試改變內核,如果我們使用水平線和垂直線內核代替交叉內核會怎樣呢?
h_line = np.array([[0,0,0], [1,1,1], [0,0,0]]) v_line = np.array([[0,1,0], [0,1,0], [0,1,0]]) fig, ax = plt.subplots(1, 2, figsize=(15, 5)) ax[0].imshow(h_line, cmap='gray'); ax[1].imshow(v_line, cmap='gray'); fig.tight_layout()
ites = [2,4,6,8,10,12,14,16,18,20] fig, ax = plt.subplots(2, 5, figsize=(17, 5)) for n, ax in enumerate(ax.flatten()): ax.set_title(f'Horizontal Iterations : {ites[n]}', fontsize = 12) new_circle = multi_erosion(circ_image, h_line, ites[n]) ax.imshow(new_circle, cmap = 'gray'); ax.axis('off') fig.tight_layout() fig, ax = plt.subplots(2, 5, figsize=(17, 5)) for n, ax in enumerate(ax.flatten()): ax.set_title(f'Vertical Iterationss : {ites[n]}', fontsize = 12) new_circle = multi_erosion(circ_image, v_line, ites[n]) ax.imshow(new_circle, cmap = 'gray'); ax.axis('off') fig.tight_layout()
正如我們所看到的,水平和垂直的腐蝕以不同的方式影響著圖像。使用水平內核我們得到一個垂直方向細長的圓;而使用垂直內核我們得到一個水平方向細長的圓。
你可能會奇怪,為什么使用垂直內核,會得到一個水平方向細長的圓呢?
因為腐蝕函數是分別尋找垂直和水平的線條,并慢慢把它們削掉。膨脹函數將會讓我們更清晰的理解這一點。
使用下面的函數設置處理的圖像、膨脹內核以及迭代次數。
def multi_dilation(image, kernel, iterations): for i in range(iterations): image = dilation(image, kernel) return image
讓我們看一下處理后的圖像有什么不同。
dilated_circle = multi_dilation(circ_image, cross, 1) linecolor = 'red' fig, ax = plt.subplots(1, 2, figsize=(12, 5)) ax[0].imshow(circ_image, cmap = 'gray'); ax[0].set_title('Original', fontsize = 19) ax[0].axvline(x = 25, color = linecolor) ax[0].axvline(x = 75, color = linecolor) ax[0].axhline(y = 25, color = linecolor) ax[0].axhline(y = 75, color = linecolor) ax[1].imshow(dilated_circle, cmap = 'gray'); ax[1].set_title('Dilated', fontsize = 19) ax[1].axvline(x = 25, color = linecolor) ax[1].axvline(x = 75, color = linecolor) ax[1].axhline(y = 25, color = linecolor) ax[1].axhline(y = 75, color = linecolor) fig.tight_layout()
可以清楚地看到圓現在已經越過了紅線,這清楚地表明它已經擴大了。現在讓我們對水平和垂直擴張進行迭代。
ites = [2,4,6,8,10,12,14,16,18,20] fig, ax = plt.subplots(2, 5, figsize=(17, 5)) for n, ax in enumerate(ax.flatten()): ax.set_title(f'Horizontal Iterations : {ites[n]}', fontsize = 12) new_circle = multi_dilation(circ_image, h_line, ites[n]) ax.imshow(new_circle, cmap = 'gray'); ax.axis('off') fig.tight_layout() fig, ax = plt.subplots(2, 5, figsize=(17, 5)) for n, ax in enumerate(ax.flatten()): ax.set_title(f'Vertical Iterationss : {ites[n]}', fontsize = 12) new_circle = multi_dilation(circ_image, v_line, ites[n]) ax.imshow(new_circle, cmap = 'gray'); ax.axis('off') fig.tight_layout()
現在可以非常清楚地看到,水平擴張增加了圖像寬度,而垂直擴張增加了圖像高度。
現在我們已經了解了膨脹與腐蝕的基本原理,下面來看一個相對復雜的圖像。
complex_image = imread('complex_image.png') imshow(complex_image);
在上面的圖像中,我們看到了水平線、垂直線和圓的混合物。我們可以使用膨脹和腐蝕函數孤立地觀察每一種形狀。
為了得到圓,我們可以先腐蝕垂直的線,再腐蝕水平的線。但要記住最后要對圖像進行膨脹,因為腐蝕函數同樣腐蝕了圓。
step_1 = multi_erosion(complex_image, h_line,3) step_2 = multi_erosion(step_1, v_line,3) step_3 = multi_dilation(step_2, h_line,3) step_4 = multi_dilation(step_3, v_line,3) steps = [step_1, step_2, step_3, step_4] names = ['Step 1', 'Step 2', 'Step 3', 'Step 4'] fig, ax = plt.subplots(2, 2, figsize=(10, 10)) for n, ax in enumerate(ax.flatten()): ax.set_title(f'{names[n]}', fontsize = 22) ax.imshow(steps[n], cmap = 'gray'); ax.axis('off') fig.tight_layout()
同樣,下面的代碼將得到水平的線。
step_1 = multi_erosion(complex_image, cross, 20) step_2 = multi_dilation(step_1, h_line, 20) step_3 = multi_dilation(step_2, v_line,2) steps = [step_1, step_2, step_3] names = ['Step 1', 'Step 2', 'Step 3'] fig, ax = plt.subplots(1, 3, figsize=(10, 10)) for n, ax in enumerate(ax.flatten()): ax.set_title(f'{names[n]}', fontsize = 22) ax.imshow(steps[n], cmap = 'gray'); ax.axis('off') fig.tight_layout()
為了得到垂直的線,我們可以創建一個新的內核。
long_v_line = np.array([[0,1,0], [0,1,0], [0,1,0], [0,1,0], [0,1,0]]) step_1 = multi_erosion(complex_image, long_v_line, 10) step_2 = multi_dilation(step_1 ,long_v_line, 10) steps = [step_1, step_2] names = ['Step 1', 'Step 2'] fig, ax = plt.subplots(1, 2, figsize=(10, 10)) for n, ax in enumerate(ax.flatten()): ax.set_title(f'{names[n]}', fontsize = 22) ax.imshow(steps[n], cmap = 'gray'); ax.axis('off') fig.tight_layout()
注意,內核并不局限于本文中提到的這幾種,可以根據不同的需求自己定義合適的內核。
以上就是使用Python怎么對圖像進行膨脹與腐蝕處理,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。