這篇文章主要介紹了python數位影像處理之高階形態學處理,現在分享給大家,也給大家做個參考。一起過來看看吧
形態學處理,除了最基本的膨脹、腐蝕、開/閉運算、黑/白帽處理外,還有一些更高級的運用,如凸包,連通區域標記,刪除小塊區域等。
1、凸包
凸包是指一個凸多邊形,這個凸多邊形將圖片中所有的白色像素點都包含在內。
函數為:
skimage.morphology.convex_hull_image(image)
輸入為二值影像,輸出一個邏輯二值影像。在凸包內的點為True, 否則為False
例:
#import matplotlib.pyplot as plt from skimage import data,color,morphology #生成二值测试图像 img=color.rgb2gray(data.horse()) img=(img<0.5)*1 chull = morphology.convex_hull_image(img) #绘制轮廓 fig, axes = plt.subplots(1,2,figsize=(8,8)) ax0, ax1= axes.ravel() ax0.imshow(img,plt.cm.gray) ax0.set_title('original image') ax1.imshow(chull,plt.cm.gray) ax1.set_title('convex_hull image')##convex_hull_image( )是將圖片中的所有目標看作一個整體,因此計算出來只有一個最小凸多邊形。如果圖中有多個目標物體,每個物體需要計算一個最小凸多邊形,則需要使用convex_hull_object()函數。 函數格式:
skimage.morphology.convex_hull_object(image,neighbors=8 )
輸入參數image是二值影像,neighbors表示是採用4連通還是8連通,預設為8連通。 範例:import matplotlib.pyplot as plt from skimage import data,color,morphology,feature #生成二值测试图像 img=color.rgb2gray(data.coins()) #检测canny边缘,得到二值图片 edgs=feature.canny(img, sigma=3, low_threshold=10, high_threshold=50) chull = morphology.convex_hull_object(edgs) #绘制轮廓 fig, axes = plt.subplots(1,2,figsize=(8,8)) ax0, ax1= axes.ravel() ax0.imshow(edgs,plt.cm.gray) ax0.set_title('many objects') ax1.imshow(chull,plt.cm.gray) ax1.set_title('convex_hull image') plt.show()
#2、連通區域標記
在二值影像中,如果兩個像素點相鄰且值相同(同為0或同為1),那麼就認為這兩個像素點在一個相互連通的區域內。而同一個連通區域的所有像素點,都用同一個數值來進行標記,這個過程就叫連通區域標記。在判斷兩個像素是否相鄰時,我們通常會採用4連通或8連通判斷。在影像中,最小的單位是像素,每個像素周圍有8個鄰接像素,常見的鄰接關係有2種:4鄰接與8鄰接。 4鄰接一共4個點,即上下左右,如下左圖所示。 8鄰接的點一共有8個,包括了對角線位置的點,如下右圖所示。 在skimage套件中,我們採用measure子模組下的label()函數來實作連通區域標記。 函數格式:skimage.measure.label(image,connectivity=None)參數中的image表示需要處理的二值影像,connectivity表示連接的模式,1代表4鄰接,2代表8鄰接。 輸出一個標記數組(labels), 從0開始標記。
import numpy as np import scipy.ndimage as ndi from skimage import measure,color import matplotlib.pyplot as plt #编写一个函数来生成原始二值图像 def microstructure(l=256): n = 5 x, y = np.ogrid[0:l, 0:l] #生成网络 mask = np.zeros((l, l)) generator = np.random.RandomState(1) #随机数种子 points = l * generator.rand(2, n**2) mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1 mask = ndi.gaussian_filter(mask, sigma=l/(4.*n)) #高斯滤波 return mask > mask.mean() data = microstructure(l=128)*1 #生成测试图片 labels=measure.label(data,connectivity=2) #8连通区域标记 dst=color.label2rgb(labels) #根据不同的标记显示不同的颜色 print('regions number:',labels.max()+1) #显示连通区域块数(从0开始标记) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4)) ax1.imshow(data, plt.cm.gray, interpolation='nearest') ax1.axis('off') ax2.imshow(dst,interpolation='nearest') ax2.axis('off') fig.tight_layout() plt.show()在程式碼中,有些地方乘以1,則可以將bool陣列快速地轉換為int陣列。 結果如圖:有10個連通的區域,標記為0-9 #如果想分別對每一個連通區域進行操作,例如計算面積、外接矩形、凸包面積等,則需要呼叫measure子模組的regionprops()函數。此函數格式為:
skimage.measure.regionprops(label_image)傳回所有連通區塊的屬性列表,常用的屬性列表如下表:
類型 | 描述 | |
int | 區域內像素點總數 | |
tuple | 邊界外接方塊(min_row, min_col, max_row, max_col) | |
array | #質心座標 | |
#int | 凸包內像素點總數 | |
#ndarray | 與邊界外接方塊同大小的凸包 | |
ndarray | 區域內像素點座標 | |
float | 離心率 | |
float | 和區域面積相同的圓的直徑 | |
int | 區域歐拉數 | |
float | 區域面積與邊界外接框面積的比率 | |
int | 區域與外接方塊之間填滿的像素點總數 | |
float | 區域週長 | |
區域標記 |
以上是python數位影像處理之高階形態學處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!