圖像分割,作為計算機視覺的基礎,是圖像理解的重要組成部分,也是圖像處理的難點之一。
那么,如何優雅且體面的圖像分割?
5行代碼、分分鐘實現的庫——PixelLib,了解一下。
當然,如此好用的項目,開源是必須的。
為什么要用到圖像分割?
雖然計算機視覺研究工作者,會經常接觸圖像分割的問題,但是我們還是需要對其做下“贅述”(方便初學者)。
我們都知道每個圖像都是有一組像素值組成。簡單來說,圖像分割就是在像素級上,對圖像進行分類的任務。
圖像分割中使用的一些“獨門秘技”,使它可以處理一些關鍵的計算機視覺任務。主要分為2類:
語義分割:就是把圖像中每個像素賦予一個類別標簽,用不同的顏色來表示。
實例分割:它不需要對每個像素進行標記,它只需要找到感興趣物體的邊緣輪廓就行。
它的身影也經常會出現在比較重要的場景中:
無人駕駛汽車視覺系統,可以有效的理解道路場景。
醫療圖像分割,可以幫助醫生進行診斷測試。
衛星圖像分析,等等。
所以,圖像分割技術的應用還是非常重要的。
接下來,我們就直奔主題,開始了解一下PixelLib,這個神奇又好用的庫。
快速安裝PixelLib
PixelLib這個庫可以非常簡單的實現圖像分割——5行代碼就可以實現語義分割和實例分割。
老規矩,先介紹一下安裝環境。
安裝最新版本的TensorFlow、Pillow、OpenCV-Python、scikit-image和PixelLib:
pip3installtensorflow pip3installpillow pip3installopencv-python pip3installscikit-image pip3installpixellib
PixelLib實現語義分割
PixelLib在執行語義分割任務時,采用的是Deeplabv3+框架,以及在pascalvoc上預訓練的Xception模型。
用在pascalvoc上預訓練的Xception模型執行語義分割:
importpixellib frompixellib.semanticimportsemantic_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”)
讓我們看一下每行代碼:
importpixellib frompixellib.semanticimportsemantic_segmentation #createdaninstanceofsemanticsegmentationclass 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,如下圖所示。
執行代碼如下:
importpixellib frompixellib.semanticimportsemantic_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”)
可以看到,在執行代碼后,保存的圖像中,所有對象都被分割了。
也可以對代碼稍作修改,獲取一張帶有目標對象分割重疊(segmentation overlay)的圖像。
segment_image.segmentAsPascalvoc(“sample1.jpg”,output_image_name=“image_new.jpg”,overlay=True)
添加了一個額外的參數,并設置為True,就生成了帶有分隔疊加的圖像。
可以通過修改下面的代碼,來檢查執行分割所需的推理時間。
importpixellib frompixellib.semanticimportsemantic_segmentation importtime 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”InferenceTime:{end-start:.2f}seconds”)
輸出如下:
InferenceTime:8.19seconds
可以看到,在圖像上執行語義分割,只用了8.19秒。
這個xception模型是用pascalvoc數據集訓練的,有20個常用對象類別。
對象及其相應的color map如下所示:
PixelLib實現實例分割
雖然語義分割的結果看起來還不錯,但在圖像分割的某些特定任務上,可能就不太理想。
在語義分割中,相同類別的對象被賦予相同的colormap,因此語義分割可能無法提供特別充分的圖像信息。
于是,便誕生了實例分割——同一類別的對象被賦予不同的colormap。
PixelLib在執行實例分割時,基于的框架是Mask RCNN,代碼如下:
importpixellib frompixellib.instanceimportinstance_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”)
同樣,我們先來拆解一下每行代碼。
importpixellib frompixellib.instanceimportinstance_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,如下圖所示。
執行代碼如下:
importpixellib frompixellib.instanceimportinstance_segmentation segment_image=instance_segmentation() segment_image.load_model(“mask_rcnn_coco.h5”) segment_image.segmentImage(“sample2.jpg”,output_image_name=“image_new.jpg”)
上圖便是保存到目錄的圖片,現在可以看到語義分割和實例分割之間的明顯區別——在實例分割中,同一類別的所有對象,都被賦予了不同的colormap。
若是想用邊界框(bounding box)來實現分割,可以對代碼稍作修改:
segment_image.segmentImage(“sample2.jpg”,output_image_name=“image_new.jpg”,show_bboxes=True)
這樣,就可以得到一個包含分割蒙版和邊界框的保存圖像。
同樣的,也可以通過代碼查詢實例分割的推理時間:
importpixellib frompixellib.instanceimportinstance_segmentation importtime 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”InferenceTime:{end-start:.2f}seconds”)
輸出結果如下:
InferenceTime:12.55seconds
可以看到,在圖像上執行實例分割,需要12.55秒的時間。
-
圖像分割
+關注
關注
4文章
182瀏覽量
17995 -
計算機視覺
+關注
關注
8文章
1698瀏覽量
45976 -
無人駕駛
+關注
關注
98文章
4054瀏覽量
120447
原文標題:簡單粗暴,5行代碼,快速實現圖像分割
文章出處:【微信號:CVSCHOOL,微信公眾號:OpenCV學堂】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論