python數(shù)字圖像處理之高級(jí)形態(tài)學(xué)處理
形態(tài)學(xué)處理,除了最基本的膨脹、腐蝕、開(kāi)/閉運(yùn)算、黑/白帽處理外,還有一些更高級(jí)的運(yùn)用,如凸包,連通區(qū)域標(biāo)記,刪除小塊區(qū)域等。
1、凸包
凸包是指一個(gè)凸多邊形,這個(gè)凸多邊形將圖片中所有的白色像素點(diǎn)都包含在內(nèi)。
函數(shù)為:
skimage.morphology.convex_hull_image(image)
輸入為二值圖像,輸出一個(gè)邏輯二值圖像。在凸包內(nèi)的點(diǎn)為T(mén)rue, 否則為False
例:
import matplotlib.pyplot as plt from skimage import data,color,morphology #生成二值測(cè)試圖像 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()是將圖片中的所有目標(biāo)看作一個(gè)整體,因此計(jì)算出來(lái)只有一個(gè)最小凸多邊形。如果圖中有多個(gè)目標(biāo)物體,每一個(gè)物體需要計(jì)算一個(gè)最小凸多邊形,則需要使用convex_hull_object()函數(shù)。
函數(shù)格式:skimage.morphology.convex_hull_object(image,neighbors=8)
輸入?yún)?shù)image是一個(gè)二值圖像,neighbors表示是采用4連通還是8連通,默認(rèn)為8連通。
例:
import matplotlib.pyplot as plt from skimage import data,color,morphology,feature #生成二值測(cè)試圖像 img=color.rgb2gray(data.coins()) #檢測(cè)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、連通區(qū)域標(biāo)記
在二值圖像中,如果兩個(gè)像素點(diǎn)相鄰且值相同(同為0或同為1),那么就認(rèn)為這兩個(gè)像素點(diǎn)在一個(gè)相互連通的區(qū)域內(nèi)。而同一個(gè)連通區(qū)域的所有像素點(diǎn),都用同一個(gè)數(shù)值來(lái)進(jìn)行標(biāo)記,這個(gè)過(guò)程就叫連通區(qū)域標(biāo)記。在判斷兩個(gè)像素是否相鄰時(shí),我們通常采用4連通或8連通判斷。在圖像中,最小的單位是像素,每個(gè)像素周?chē)?個(gè)鄰接像素,常見(jiàn)的鄰接關(guān)系有2種:4鄰接與8鄰接。4鄰接一共4個(gè)點(diǎn),即上下左右,如下左圖所示。8鄰接的點(diǎn)一共有8個(gè),包括了對(duì)角線位置的點(diǎn),如下右圖所示。
在skimage包中,我們采用measure子模塊下的label()函數(shù)來(lái)實(shí)現(xiàn)連通區(qū)域標(biāo)記。
函數(shù)格式:
skimage.measure.label(image,connectivity=None)
參數(shù)中的image表示需要處理的二值圖像,connectivity表示連接的模式,1代表4鄰接,2代表8鄰接。
輸出一個(gè)標(biāo)記數(shù)組(labels), 從0開(kāi)始標(biāo)記。
import numpy as np import scipy.ndimage as ndi from skimage import measure,color import matplotlib.pyplot as plt #編寫(xiě)一個(gè)函數(shù)來(lái)生成原始二值圖像 def microstructure(l=256): n = 5 x, y = np.ogrid[0:l, 0:l] #生成網(wǎng)絡(luò) mask = np.zeros((l, l)) generator = np.random.RandomState(1) #隨機(jī)數(shù)種子 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 #生成測(cè)試圖片 labels=measure.label(data,connectivity=2) #8連通區(qū)域標(biāo)記 dst=color.label2rgb(labels) #根據(jù)不同的標(biāo)記顯示不同的顏色 print('regions number:',labels.max()+1) #顯示連通區(qū)域塊數(shù)(從0開(kāi)始標(biāo)記) 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數(shù)組快速地轉(zhuǎn)換為int數(shù)組。
結(jié)果如圖:有10個(gè)連通的區(qū)域,標(biāo)記為0-9
如果想分別對(duì)每一個(gè)連通區(qū)域進(jìn)行操作,比如計(jì)算面積、外接矩形、凸包面積等,則需要調(diào)用measure子模塊的regionprops()函數(shù)。該函數(shù)格式為:
skimage.measure.regionprops(label_image)
返回所有連通區(qū)塊的屬性列表,常用的屬性列表如下表:
屬性名稱(chēng) | 類(lèi)型 | 描述 |
area | int | 區(qū)域內(nèi)像素點(diǎn)總數(shù) |
bbox | tuple | 邊界外接框(min_row, min_col, max_row, max_col) |
centroid | array | 質(zhì)心坐標(biāo) |
convex_area | int | 凸包內(nèi)像素點(diǎn)總數(shù) |
convex_image | ndarray | 和邊界外接框同大小的凸包 |
coords | ndarray | 區(qū)域內(nèi)像素點(diǎn)坐標(biāo) |
Eccentricity | float | 離心率 |
equivalent_diameter | float | 和區(qū)域面積相同的圓的直徑 |
euler_number | int | 區(qū)域歐拉數(shù) |
extent | float | 區(qū)域面積和邊界外接框面積的比率 |
filled_area | int | 區(qū)域和外接框之間填充的像素點(diǎn)總數(shù) |
perimeter | float | 區(qū)域周長(zhǎng) |
label | int | 區(qū)域標(biāo)記 |
3、刪除小塊區(qū)域
有些時(shí)候,我們只需要一些大塊區(qū)域,那些零散的、小塊的區(qū)域,我們就需要?jiǎng)h除掉,則可以使用morphology子模塊的remove_small_objects()函數(shù)。
函數(shù)格式:skimage.morphology.remove_small_objects(ar,min_size=64,connectivity=1,in_place=False)
參數(shù):
ar: 待操作的bool型數(shù)組。
min_size: 最小連通區(qū)域尺寸,小于該尺寸的都將被刪除。默認(rèn)為64.
connectivity: 鄰接模式,1表示4鄰接,2表示8鄰接
in_place: bool型值,如果為T(mén)rue,表示直接在輸入圖像中刪除小塊區(qū)域,否則進(jìn)行復(fù)制后再刪除。默認(rèn)為False.
返回刪除了小塊區(qū)域的二值圖像。
import numpy as np import scipy.ndimage as ndi from skimage import morphology import matplotlib.pyplot as plt #編寫(xiě)一個(gè)函數(shù)來(lái)生成原始二值圖像 def microstructure(l=256): n = 5 x, y = np.ogrid[0:l, 0:l] #生成網(wǎng)絡(luò) mask = np.zeros((l, l)) generator = np.random.RandomState(1) #隨機(jī)數(shù)種子 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) #生成測(cè)試圖片 dst=morphology.remove_small_objects(data,min_size=300,connectivity=1) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4)) ax1.imshow(data, plt.cm.gray, interpolation='nearest') ax2.imshow(dst,plt.cm.gray,interpolation='nearest') fig.tight_layout() plt.show()
在此例中,我們將面積小于300的小塊區(qū)域刪除(由1變?yōu)?),結(jié)果如下圖:
4、綜合示例:閾值分割+閉運(yùn)算+連通區(qū)域標(biāo)記+刪除小區(qū)塊+分色顯示
import numpy as np import matplotlib.pyplot as plt import matplotlib.patches as mpatches from skimage import data,filter,segmentation,measure,morphology,color #加載并裁剪硬幣圖片 image = data.coins()[50:-50, 50:-50] thresh =filter.threshold_otsu(image) #閾值分割 bw =morphology.closing(image > thresh, morphology.square(3)) #閉運(yùn)算 cleared = bw.copy() #復(fù)制 segmentation.clear_border(cleared) #清除與邊界相連的目標(biāo)物 label_image =measure.label(cleared) #連通區(qū)域標(biāo)記 borders = np.logical_xor(bw, cleared) #異或 label_image[borders] = -1 image_label_overlay =color.label2rgb(label_image, image=image) #不同標(biāo)記用不同顏色顯示 fig,(ax0,ax1)= plt.subplots(1,2, figsize=(8, 6)) ax0.imshow(cleared,plt.cm.gray) ax1.imshow(image_label_overlay) for region in measure.regionprops(label_image): #循環(huán)得到每一個(gè)連通區(qū)域?qū)傩约? #忽略小區(qū)域 if region.area < 100: continue #繪制外包矩形 minr, minc, maxr, maxc = region.bbox rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr, fill=False, edgecolor='red', linewidth=2) ax1.add_patch(rect) fig.tight_layout() plt.show()
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
selenium+python實(shí)現(xiàn)自動(dòng)登錄腳本
下面小編就為大家分享一篇selenium+python實(shí)現(xiàn)自動(dòng)登錄腳本,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04PyTorch的張量tensor和自動(dòng)求導(dǎo)autograd詳解
這篇文章主要介紹了PyTorch的張量tensor和自動(dòng)求導(dǎo)autograd,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02Python2與Python3的區(qū)別點(diǎn)整理
在本篇文章里小編給大家整理的是關(guān)于Python2與Python3的區(qū)別點(diǎn)整理內(nèi)容,需要的朋友們可以參考下。2019-12-12python實(shí)現(xiàn)輸入任意一個(gè)大寫(xiě)字母生成金字塔的示例
這篇文章主要介紹了python實(shí)現(xiàn)輸入任意一個(gè)大寫(xiě)字母生成金字塔的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10Python 批量讀取文件中指定字符的實(shí)現(xiàn)
這篇文章主要介紹了Python 批量讀取文件中指定字符的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03解決django后臺(tái)樣式丟失,css資源加載失敗的問(wèn)題
今天小編就為大家分享一篇解決django后臺(tái)樣式丟失,css資源加載失敗的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06Pytorch?Conda環(huán)境pack打包遷移報(bào)錯(cuò)的處理方案
這篇文章主要介紹了Pytorch?Conda環(huán)境pack打包遷移報(bào)錯(cuò)的處理方案,文中通過(guò)代碼示例和圖文結(jié)合的方式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-07-07Selenium獲取登錄Cookies并添加Cookies自動(dòng)登錄的方法
這篇文章主要介紹了Selenium獲取登錄Cookies并添加Cookies自動(dòng)登錄的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12