1. 程式人生 > >影象處理中媲美matlab的python包——scikit-image(skimage)包的用法詳解

影象處理中媲美matlab的python包——scikit-image(skimage)包的用法詳解

前言:

基於python的圖片處理包還是很多的,比如PIL,Pillow, opencv, scikit-image等。其中,PIL和Pillow只提供最基礎的數字影象處理,功能有限;opencv本質上是一個c++庫,只是提供了python的介面,官方更新速度非常慢,而且安裝很不容易。綜合來看,scikit-image是基於scipy的一款影象處理包,它功能非常齊全,同時將圖片作為numpy陣列進行處理,幾乎集合了matlab的所有影象處理功能,在資料的處理方式,函式名字等方面對matlab的模仿姿勢非常到位。

更為重要的是,作為python的一個影象處理包,這個包是完全開源免費的,而且可以依託於python強大的功能,與tensorflow等軟體配合使用於主流的深度學習等領域。因此,用scikit-image進行影象處理是一個非常好的選擇,matlab能幹的事情它都能幹,matlab不能幹的事情他也可以,個人認為在數字影象處理領域,它是完全可以代替matlab的。價格昂貴且介面並不怎麼美觀的matlab簡直要哭暈在廁所。

當然,如果有一定的程式設計基礎,學習這個包最好的方法是去看官方文件,scikit-image官方文件,對於初學者來說,可以先看以下通俗版的介紹入門。

一、安裝。

二、匯入scikit-image包

這個包有非常多的子模組,分別負責不同的功能,所以在匯入的時候,對於不同的功能可以分別匯入不同的模組,各模組的功能如下:

子模組名稱 主要實現功能
io 讀取、儲存和顯示圖片或視訊
data 提供一些測試圖片和樣本資料
color 顏色空間變換
filters 影象增強、邊緣檢測、排序濾波器、自動閾值等
draw 操作於numpy陣列上的基本圖形繪製,包括線條、矩形、圓和文字等
transform 幾何變換或其它變換,如旋轉、拉伸和拉東變換等
morphology 形態學操作,如開閉運算、骨架提取等
exposure 圖片強度調整,如亮度調整、直方圖均衡等
feature 特徵檢測與提取等
measure 影象屬性的測量,如相似性或等高線等
segmentation 影象分割
restoration 影象恢復
util 通用函式

下邊分別敘述

from skimage import 函式名

1、讀取,顯示影象。(用到的模組:io)

from skimage import io
img=io.imread('圖片路徑',as_grey = bool值)
io.imshow(img)

其中,as_grey屬性如果是True,則讀入彩圖之後自動轉換成灰度影象,否則讀入彩圖,預設為False。
讀入圖片之後,可以獲取圖片的各種屬性

print(type(img))  #顯示型別
print(img.shape)  #顯示尺寸
print(img.shape[0])  #圖片寬度
print(img.shape[1])  #圖片高度
print(img.shape[2])  #圖片通道數
print(img.size)   #顯示總畫素個數
print(img.max())  #最大畫素值
print(img.min())  #最小畫素值
print(img.mean()) #畫素平均值

2、儲存影象

讀取時matlab的語法幾乎相同,寫入圖片檔案時,將matlab中的imwrite()函式改成imsave()函式即可。

from skimage import io,data
img=io.imread('圖片路徑',as_grey = bool值)#以上的讀取圖片函式
io.imshow(img)
io.imsave('儲存路徑',img)

儲存圖片的時候也可以隨便儲存為不同的格式(jpg,png等)。

對於二值影象來說,用io.imsave()函式直接儲存會得到一張黑色的影象,個人覺得是因為儲存的時候程式依舊以為圖片的數值範圍是0~255,需要轉換一下資料型別,有知道的更方便的解決辦法的可以在評論區交流

3、影象的裁剪,縮放。(用到的模組:transform)

1)改變圖片尺寸resize

同樣,提供了skimage.transform.resize(image, output_shape)函式,和matlab裡重新調整影象大小的語法沒有絲毫區別。

image: 需要改變尺寸的圖片

output_shape: 新的圖片尺寸

from skimage import transform,io
import matplotlib.pyplot as plt#用於顯示影象
img=io.imread('圖片路徑',as_grey = bool值)
dst=transform.resize(img, (長, 寬))
plt.figure('resize')
plt.subplot(121)
plt.title('before resize')
plt.imshow(img,plt.cm.gray)
plt.subplot(122)
plt.title('before resize')
plt.imshow(dst,plt.cm.gray)
plt.show()

可以將圖片變成80*60大小。

4、圖片的連通域標記與選擇(用到的模組:measure)

1)獲取連通域及其屬性

獲取影象連通域是影象處理中比較高階的功能,matlab可以通過函式直接獲取影象的連通域,在skimage包中,我們同樣可以採用measure子模組下的label()函式來實現相同的效果。

函式格式:

from skimage import measure
labels = measure.label(二值影象,connectivity=None)
  • connectivity表示連線的模式,1代表4鄰接,2代表8鄰接。

返回一個與影象同樣大小的陣列,背景都是0,對於前景的連通域從1開始往上標記。

當然,此時做到的只是對連通域進行標記給人看,如果想分別對每一個連通區域進行操作,比如計算面積、外接矩形、凸包面積等,則需要呼叫measure子模組的regionprops()函式。在同上匯入measure包之後,該函式格式為:
label_att = measure.regionprops(label_image)
這樣,我們就可以從“label_att”這個數組裡獲取影象裡任意一個連通域的屬性,屬性列表如下:

屬性名稱 型別 描述
area int 區域內畫素點總數
bbox tuple 邊界外接框(min_row, min_col, max_row, max_col)
centroid array 質心座標
convex_area int 凸包內畫素點總數
convex_image ndarray 和邊界外接框同大小的凸包
coords ndarray 區域內畫素點座標
Eccentricity float 離心率
equivalent_diameter float 和區域面積相同的圓的直徑
euler_number int 區域尤拉數
extent float 區域面積和邊界外接框面積的比率
filled_area int 區域和外接框之間填充的畫素點總數
perimeter float 區域周長
label int 區域標記

這裡需要注意的是:measure.label函式獲取的連通域背景是0,前景的連通域其實是從1開始計算,而measure.regionprops函式獲取的連通域不包含背景,前景的連通域屬性就是從0開始的。
下面舉一個例子:
隨便找一張圖片如下:
測試圖片(彩圖)
執行程式碼如下:

from skimage import io,filters,measure 
img = io.imread('test.jpg',as_grey=True) #讀取圖片
thresh = filters.threshold_otsu(img)  #用otsu演算法確定最佳分割閾值
bwimg =(img>=(thresh))  #用閾值進行分割,生成二值影象
labels = measure.label(bwimg)  #標記連通域
label_att = measure.regionprops(labels) #獲取各個連通域的屬性。

labels值
label_att值

可以看到labels找出了5個連通域,而label_att卻只有四個連通域的屬性,這是因為不包括背景的連通域的屬性。

2)刪除小塊區域

圖片難免會有噪聲,在以上獲取連通域處理的時候,噪點也會算作是一個很小的連通域,morphology子模組的remove_small_objects()函式提供了方便的噪點去除功能。函式格式(一般與上一個函式連用):

from skimage import morphology
img1 = morphology.remove_small_objects(ar, min_size=要刪除的連通域大小閾值, connectivity=1,in_place=False)

img1是刪除了小於連通域面積閾值的二值影象。
其中,各引數含義如下:

  • ar: 上邊的獲取的標記好連通域的陣列
  • connectivity: 鄰接模式,1表示4鄰接,2表示8鄰接
  • in_place: bool型值,如果為True,表示直接在輸入影象中刪除小塊區域,否則進行復制後再刪除。預設為False.

附錄:

scikit-image這個包對matlab的模仿甚至還體現在很多細節上,比如說,matlab會自帶一些圖片讓使用者進行測試,如果我們不想從外部讀取圖片,就可以直接使用這些示例圖片對函式進行測試,scikit-image包同樣也有如下功能:
而且使用方法也很簡單:

from skimage import io,data
img=data.lena()
io.imshow(img)
astronaut 宇航員圖片
coffee 一杯咖啡圖片
lena lena美女圖片
camera 拿相機的人圖片
coins 硬幣圖片
moon 月亮圖片
checkerboard 棋盤圖片
horse 馬圖片
page 書頁圖片
chelsea 小貓圖片
hubble_deep_field 星空圖片
text 文字圖片
clock 時鐘圖片
immunohistochemistry 結腸圖片

圖片名對應的就是函式名,這些示例圖片存放在skimage的安裝目錄下面,路徑名稱為data_dir,也可以將這個路徑打印出來:

from skimage import data_dir
print(data_dir)

參考資料: