金磊 發自 凹非寺

量子位 報道 | 公眾號 QbitAI

影象分割

,作為計算機視覺的基礎,是影象理解的重要組成部分,也是影象處理的難點之一。

那麼,如何優雅且體面的影象分割?

5行程式碼、分分鐘實現的庫——

PixelLib

,瞭解一下。

5行程式碼,快速實現影象分割,程式碼逐行詳解,手把手教你處理影象 | 開源

當然,如此好用的專案,開源是必須的。

為什麼要用到影象分割?

雖然計算機視覺研究工作者,會經常接觸影象分割的問題,但是我們還是需要對其做下“贅述”(方便初學者)。

我們都知道每個影象都是有一組畫素值組成。簡單來說,影象分割就是在畫素級上,對影象進行分類的任務。

影象分割中使用的一些“獨門秘技”,使它可以處理一些關鍵的計算機視覺任務。主要分為2類:

語義分割

:就是把影象中每個畫素賦予一個類別標籤,用不同的顏色來表示。

例項分割

:它不需要對每個畫素進行標記,它只需要找到感興趣物體的邊緣輪廓就行。

它的身影也經常會出現在比較重要的場景中:

無人駕駛汽車視覺系統,可以有效的理解道路場景。

醫療影象分割,可以幫助醫生進行診斷測試。

衛星影象分析,等等。

所以,影象分割技術的應用還是非常重要的。

接下來,我們就直奔主題,開始瞭解一下PixelLib,這個神奇又好用的庫。

快速安裝PixelLib

PixelLib這個庫可以非常簡單的實現影象分割——5行程式碼就可以實現語義分割和例項分割。

老規矩,先介紹一下

安裝環境

安裝最新版本的TensorFlow、Pillow、OpenCV-Python、scikit-image和PixelLib:

pip3 install tensorflow

pip3 install pillow

pip3 install opencv-python

pip3 install scikit-image

pip3 install pixellib

PixelLib實現語義分割

PixelLib在執行語義分割任務時,採用的是Deeplabv3+框架,以及在pascalvoc上預訓練的Xception模型。

用在pascalvoc上預訓練的Xception模型執行語義分割:

import pixellib

from pixellib。semantic import semantic_segmentation

segment_image = semantic_segmentation()

segment_image。load_pascalvoc_model(“deeplabv3_xception_tf_dim_ordering_tf_kernels。h5”)

segment_image。segmentAsPascalvoc(“path_to_image”, output_image_name = “path_to_output_image”)

讓我們看一下每行程式碼:

import pixellib

from pixellib。semantic import semantic_segmentation

#created an instance of semantic segmentation class

segment_image = semantic_segmentation()

用於執行語義分割的類,是從pixellib匯入的,建立了一個類的例項。

segment_image。load_pascalvoc_model(“deeplabv3_xception_tf_dim_ordering_tf_kernels。h5”)

呼叫函式來載入在pascal voc上訓練的xception模型(xception模型可以從文末傳送門連結處下載)。

segment_image。segmentAsPascalvoc(“path_to_image”, output_image_name = “path_to_output_image”)

這是對影象進行分割的程式碼行,這個函式包含了兩個引數:

path_to_image:影象被分割的路徑。

path_to_output_image:儲存輸出影象的路徑,影象將被儲存在你當前的工作目錄中。

接下來,

上圖,實戰

影象檔案命名為:sample1。jpg,如下圖所示。

5行程式碼,快速實現影象分割,程式碼逐行詳解,手把手教你處理影象 | 開源

執行程式碼如下:

import pixellib

from pixellib。semantic import semantic_segmentation

segment_image = semantic_segmentation()

segment_image。load_pascalvoc_model(“deeplabv3_xception_tf_dim_ordering_tf_kernels。h5”)

segment_image。segmentAsPascalvoc(“sample1。jpg”, output_image_name = “image_new。jpg”)

5行程式碼,快速實現影象分割,程式碼逐行詳解,手把手教你處理影象 | 開源

可以看到,在執行程式碼後,儲存的影象中,所有物件都被分割了。

也可以對程式碼稍作修改,獲取一張帶有目標物件分段重疊(segmentation overlay)的影象。

segment_image。segmentAsPascalvoc(“sample1。jpg”, output_image_name = “image_new。jpg”, overlay = True)

添加了一個額外的引數,並設定為True,就生成了帶有分段疊加的影象。

5行程式碼,快速實現影象分割,程式碼逐行詳解,手把手教你處理影象 | 開源

可以透過修改下面的程式碼,來檢查執行分割所需的推理時間。

import pixellib

from pixellib。semantic import semantic_segmentation

import time

segment_image = semantic_segmentation()

segment_image。load_pascalvoc_model(“pascal。h5”)

start = time。time()

segment_image。segmentAsPascalvoc(“sample1。jpg”, output_image_name= “image_new。jpg”)

end = time。time()

print(f”Inference Time: {end-start:。2f}seconds”)

輸出如下:

Inference Time: 8。19seconds

可以看到,在影象上執行語義分割,只用了8。19秒。

這個xception模型是用pascalvoc資料集訓練的,有20個常用物件類別。

物件及其相應的color map如下所示:

5行程式碼,快速實現影象分割,程式碼逐行詳解,手把手教你處理影象 | 開源

PixelLib實現例項分割

雖然語義分割的結果看起來還不錯,但在影象分割的某些特定任務上,可能就不太理想。

在語義分割中,相同類別的物件被賦予相同的colormap,因此語義分割可能無法提供特別充分的影象資訊。

於是,便誕生了

例項分割

——同一類別的物件被賦予不同的colormap。

PixelLib在執行例項分割時,基於的框架是Mask RCNN,程式碼如下:

import pixellib

from pixellib。instance import instance_segmentation

segment_image = instance_segmentation()

segment_image。load_model(“mask_rcnn_coco。h5”)

segment_image。segmentImage(“path_to_image”, output_image_name = “output_image_path”)

同樣,我們先來拆解一下每行程式碼。

import pixellib

from pixellib。instance import instance_segmentation

segment_image = instance_segmentation()

匯入了用於執行例項分割的類,建立了該類的一個例項。

segment_image。load_model(“mask_rcnn_coco。h5”)

這是載入 Mask RCNN 模型來執行例項分割的程式碼(Mask RCNN模型可以從文末傳送門連結處下載)。

segment_image。segmentImage(“path_to_image”, output_image_name = “output_image_path”)

這是對影象進行例項分割的程式碼,它需要兩個引數:

path_to_image:模型所要預測影象的路徑。

output_image_name:儲存分割結果的路徑,將被儲存在當前的工作目錄中。

上圖,實戰第二彈!

影象檔案命名為:sample2。jpg,如下圖所示。

5行程式碼,快速實現影象分割,程式碼逐行詳解,手把手教你處理影象 | 開源

執行程式碼如下:

import pixellib

from pixellib。instance import instance_segmentation

segment_image = instance_segmentation()

segment_image。load_model(“mask_rcnn_coco。h5”)

segment_image。segmentImage(“sample2。jpg”, output_image_name = “image_new。jpg”)

5行程式碼,快速實現影象分割,程式碼逐行詳解,手把手教你處理影象 | 開源

上圖便是儲存到目錄的圖片,現在可以看到語義分割和例項分割之間的明顯區別——在例項分割中,同一類別的所有物件,都被賦予了不同的colormap。

若是想用邊界框(bounding box)來實現分割,可以對程式碼稍作修改:

segment_image。segmentImage(“sample2。jpg”, output_image_name = “image_new。jpg”, show_bboxes = True)

這樣,就可以得到一個包含分割蒙版和邊界框的儲存影象。

5行程式碼,快速實現影象分割,程式碼逐行詳解,手把手教你處理影象 | 開源

同樣的,也可以透過程式碼查詢例項分割的推理時間:

import pixellib

from pixellib。instance import instance_segmentation

import time

segment_image = instance_segmentation()

segment_image。load_model(“mask_rcnn_coco。h5”)

start = time。time()

segment_image。segmentImage(“former。jpg”, output_image_name= “image_new。jpg”)

end = time。time()

print(f”Inference Time: {end-start:。2f}seconds”)

輸出結果如下:

Inference Time: 12。55 seconds

可以看到,在影象上執行例項分割,需要12。55秒的時間。

最後,奉上專案、模型下載地址,快去試試吧~

傳送門

PixelLib專案地址:

https://

github。com/ayoolaolafen

wa/PixelLib

xception模型下載地址:

https://

github。com/bonlime/kera

s-deeplab-v3-plus/releases/download/1。1/deeplabv3_xception_tf_dim_ordering_tf_kernels。h5

Mask RCNN模型下載地址:

https://

github。com/matterport/M

ask_RCNN/releases/download/v2。0/mask_rcnn_coco。h5

—完—

@量子位 · 追蹤AI技術和產品新動態

深有感觸的朋友,歡迎贊同、關注、分享三連վ‘ᴗ’ ի ❤