天天看點

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

全文共6625字,預計學習時長13分鐘或更長

劃重點!!!本文主要内容:

· Mask R-CNN是一種先進的算法架構,用于解決圖像分割問題

· 本文将采用逐漸推進、層層推進的方式來剖析Mask R-CNN的工作原理

· 本文還将探析如何用Python實作Mask R-CNN及其在圖像處理的運用

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

圖檔來源:unsplash.com/@mcnoble

自動駕駛系統所囊括的計算機視覺技術複雜巧妙,種類繁多,在資料科學家眼中,這種複雜性與混合性堪比夢中天籁,引人入勝。

是以,筆者開始研究這一系統,試圖了解自動駕駛賦予汽車的這雙“火眼金睛”的背後,究竟隐藏着何等玄機。僅憑一個物體檢測架構可能行不通,因為它僅能識别對象,并用某種固定的形狀将其标出。

然而若運用于現實中,這種方法風險很大。試想,倘若前方有一處急轉彎,系統隻在道路上給出一個矩形辨別,這樣以來車輛很有可能判斷不出是該避讓還是徑直上前,車禍一觸即發!

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

是以,對新技術的訴求應運而生,該技術須能識别具體路況,以指引車輛順利過彎。

到底什麼樣的黑科技能夠滿足這一需求呢—— Mask R-CNN閃亮登場!

本文将簡要闡釋何為圖像分割,并以此引入全文的核心主角—— Mask R-CNN算法架構。最後本文将探析如何用Python實作Mask R-CNN架構。

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

目錄

1. 圖像分割概覽

2. 剖析Mask R-CNN

3. 實作Mask R-CNN的步驟

4. 實作Mask R-CNN

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

1. 圖像分割概覽

讓我們先來簡單回顧一下圖像分割:圖像分割即為圖檔的每個對象建立一個像素級的掩膜,該技術可使大家對圖像中的對象有更深入的了解。下圖将助你了解何為圖像分割。

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

如圖所示,每個對象(即該圖中的每個單元)已彼此分離,這就是圖像分割的工作原理。

圖像分割可分為兩種,語義分割與執行個體分割,具體執行個體詳見下文。

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

左圖五個對象均為人,是以語義分割會将這五個對象視為一個整體。而右圖同樣也有五個對象(亦均為人),但同一類别的不同對象在此被視為不同的執行個體,這就是執行個體分割。

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

2. 剖析Mask-CNN

Mask R-CNN可算作是Faster R-CNN的更新版。Faster R-CNN廣泛用于對象檢測。對于給定圖像,它會給圖中每個對象加上類别标簽與邊界框坐标。如果你輸入下圖:

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

Fast R-CNN将會傳回如下結果:

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

Mask R-CNN架構是以Faster R-CNN為基礎而架構的。是以,針對給定圖像, Mask R-CNN不僅會給每個對象添加類标簽與邊界框坐标,還會傳回其對象掩膜。

先來分析Faster R-CNN的工作原理,因為這也助于促進對Mask R-CNN的直覺感受。

· Faster R-CNN通過ConvNet從圖檔中提取特征圖

· 特征圖通過區域候選網絡 (RPN) 予以傳遞,該網絡會傳回候選邊界框

· 應用Rol池化層,将所有候選區域修正到同一尺寸

· 将候選區域傳遞到全連接配接層,将對象邊界框分類及輸出

一旦掌握了Faster R-CNN 的工作原理, Mask R-CNN 自然也就易如反掌。接下來将從輸入到預測類标簽、邊界框與對象掩膜,逐漸剖析Mask R-CNN 的背後玄機。

骨幹模型 (Backbone Model)

與在Faster R-CNN 中從圖檔提取特征圖所用的ConvNet相似,在Mask R-CNN中提取特征圖用的是殘差網絡 101結構。是以,先選取圖檔,用殘差網絡 101結構提取特征,這些特征便是下一層的輸入資料。

區域候選網絡 (RPN)

将上一步提取的特征圖應用于區域候選網絡 (RPN)。這基本能預測出一個對象是否位于該區域。該步驟可得到那些可能包含某些對象的區域或特征圖。

感興趣區域 (RoI)

從RPN獲得的區域可能形狀不一。是以,須将所得區域應用于一個池化層,将所有區域轉換為同一形狀。随後,這些區域通過全連接配接網絡,以此預測出類标簽與邊界框。

在該步驟之前,一切似乎與Faster R-CNN 并無二緻。不過RoI便是這兩者的差別所在。除此之外,另一個差別在于,Mask R-CNN可建立掩膜。

我們先算出感興的區域,以減少計算時間。在所有預測區域中,原标記框可用于計算交并比。計算公式如下:

交并比=交集區域/并集區域

隻有當交并比大于等于0.5時,這一區域方為感興趣區域;若小于0.5,該區域将不予考慮。計算所有區域的交并比,并選出交并比大于0.5的區域。

以下圖為例:

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

紅框即該圖的原标記框,如下圖所示,通過RPN得出4個區域:

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

如圖所示,框1與框2的交并比應該小于0.5,而框3與框4的交并比約大于0.5。是以可判定框3與框4屬于該圖的感興趣區域,而框1及框2可棄之不用。

接下來便是Mask R-CNN操作流程的尾聲。

分割掩膜

基于交并比值獲得感興趣區域後,給已有架構加上一個掩膜分支,每個囊括特定對象的區域都會被賦予一個掩膜。每個區域都會被賦予一個28 X 28掩膜,并按比例放大以便推斷。

詳見下圖:

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

該圖分割掩膜效果如下:

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

到此,圖上所有對象已被分割。這就是Mask R-CNN給圖中所有對象預測掩膜的最後一步。

謹記, Mask R-CNN的訓練周期很長。筆者曾用享有盛名的COCO資料集訓練Mask R-CNN ,耗時長達一到兩天。受篇幅所限,本文不會讨論Mask R-CNN的訓練詳情。

不過筆者會用到COCO資料集中Mask R-CNN的預訓練權值。在探析如何用Python編碼前,先來了解Mask R-CNN在執行執行個體分割時的所需步驟。

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

3. 實作Mask R-CNN的步驟

以下即圖像分割環節。該環節所用的Mask R-CNN架構 是由Facebook AI Research(FAIR) 的資料科學家與研究員聯手打造。

Mask R-CNN分割圖像所要遵循的步驟,詳見下文。

第1步:克隆知識庫

首先,克隆mask rcnn知識庫,其庫應具有Mask R-CNN架構。可利用以下指令克隆該知識庫:

git clone https://github.com/matterport/Mask_RCNN.git

克隆完成後,需要安裝Mask R-CNN所需的依賴庫。

第2步:安裝依賴庫

以下是Mask R-CNN的所有依賴庫:

· numpy

· scipy

· Pillow

· cython

· matplotlib

· scikit-image

· tensorflow>=1.3.0

· keras>=2.0.8

· opencv-python

· h5py

· imgaug

· IPython

使用Mask R-CNN架構前必須安裝所有依賴庫。

第3步:下載下傳預訓練模型權值

接下來,需要下載下傳預訓練模型權值。可以采用此連結下載下傳預訓練模型權值:https://github.com/matterport/Mask_RCNN/releases。這些權值從MS COCO資料集所訓練的一種模型而來。下載下傳完成後,粘貼此檔案于第一步克隆的Mask_RCNN知識庫樣本檔案夾中。

第4步:圖像預測

最後,采用Mask R-CNN架構和預訓練模型權值生成圖像預測。

四步完成後,開始轉入Jupyter Notebook。用python實作上述所有代碼并為圖像中各個對象生成掩膜、類和邊界框

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

4. 基于Python的Mask R-CNN實作

為了執行所有本節将談到的代碼塊,須建立一個新的Python筆記本,然後将其放入所克隆的Mask_RCNN “樣本”檔案夾中。

開始導入所需程式庫:

import osimport sysimport randomimport mathimport numpy as npimport skimage.
ioimport matplotlibimport matplotlib.pyplot as plt
# Root directory of the projectROOT_DIR = os.path.abspath("../")
import warningswarnings.filterwarnings("ignore")
# Import Mask RCNNsys.path.append(ROOT_DIR)  
# To find local version of the libraryfrom mrcnn import utilsimport mrcnn.
model as modellibfrom mrcnn import visualize
# Import COCO configsys.path.append(os.path.join(ROOT_DIR, "samples/coco/"))  
# To find local versionimport coco%matplotlib inline      

接下來,将對預訓練權值及待分割的圖像定義路徑:

# Directory to save logs and trained modelMODEL_DIR = os.path.join(ROOT_DIR, "logs")
# Local path to trained weights fileCOCO_MODEL_PATH = os.path.join('', "mask_rcnn_coco.h5")
# Download COCO trained weights from Releases if neededif not os.path.exists(COCO_MODEL_PATH):    
utils.download_trained_weights(COCO_MODEL_PATH)
# Directory of images to run detection onIMAGE_DIR = os.path.join(ROOT_DIR, "images")      

若未将權值放置于樣本檔案夾,則會重新下載下傳權值。現在,建立推理類,用于推斷Mask R-CNN模型:

class InferenceConfig(coco.CocoConfig):    
# Set batch size to 1 since we'll be running inference on    
# one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU    
GPU_COUNT = 1    
IMAGES_PER_GPU = 1config = InferenceConfig()config.display()      
代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

由此彙總可推斷出什麼呢?可看到即将使用的Mask R-CNN模型的多項性能規格。

如上所述,該算法基幹是殘差網絡101。鑒于其訓練資料集為COCO,故傳回的掩膜形狀為28×28。總計81類(包括背景)。

此外,還有其他多項資料如:

· 輸入形狀

· 待用圖形處理器編号

· 驗證步驟等

加載權值

接下來,建立模型,加載已下載下傳的預訓練模型權值。確定預訓練權值與筆記本處在同一檔案夾中,否則,必須給出該權值檔案夾的位置:

# Create model object in inference mode.model = modellib.
MaskRCNN(mode="inference", model_dir='mask_rcnn_coco.hy', config=config)
# Load weights trained on MS-COCOmodel.load_weights('mask_rcnn_coco.h5', by_name=True)      

現在,定義COCO資料集類别,供預測階段使用:

# COCO Class namesclass_names = ['BG', 'person', 'bicycle', 
'car', 'motorcycle', 'airplane',               
'bus', 'train', 'truck', 'boat', 'traffic light',               
'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird',               
'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear',               
'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie',               
'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',               
'kite', 'baseball bat', 'baseball glove', 'skateboard',               
'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',              
 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',               
'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',               
'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed',               
'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote',               
'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',               
'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',               
'teddy bear', 'hair drier', 'toothbrush']      

加載圖像,觀察模型運作情況。測試圖像任意選擇。

# Load a random image from the images folderimage = skimage.io.imread('sample.jpg')
# original imageplt.figure(figsize=(12,10))skimage.io.imshow(image)      
代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

此即測試用圖。兩輛汽車(一輛在前,一輛在後)及一輛自行車清晰可辨。

進行預測

開始預測!使用帶有預訓練權值的Mask R-CNN模型,并觀察其圖像分割效果。首先對圖像進行預測,繪制結果并将其可視化:

# Run detectionresults = model.detect([image], verbose=1)
# Visualize resultsr = results[0]visualize.
display_instances(image, r['rois'], 
r['masks'], r['class_ids'], class_names, r['scores'])      
代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

有趣!該模型成功地将圖像中的汽車和自行車進行了分割。每個掩膜或所分割對象均可分開研究。其實作方式詳見下文。

首先将模型預測的所有掩膜存儲在掩膜變量中。現在,這些掩膜是布爾型(True和False),是以需要将其轉換為二進制(1和0):

mask = r['masks']mask = mask.astype(int)mask.shape      

輸出:

(480,640,3)      

此會得出一個0和1的數組,其中0表示在那個特定像素處無對象存在,1表示在該像素處有對象存在。注意,掩膜的形狀與原始圖像的形狀相似(這可以通過輸出原始圖像的形狀來進行驗證)

然而,掩膜形狀裡的3不表示路徑,相反,它代表模型所分割的對象數量。由于模型在上述樣本圖像中已識别了3個對象,是以掩模的形狀為 (480,640,3) 。如果有5個對象,則此形狀應為 (480,640,5) 。

有了原始圖像以及其掩膜數組。為了輸出或獲得各個圖像片段,将建立for loop函數,後将每個掩模與原始圖像相乘,以求分割後的各圖像片段:

for i in range(mask.shape[2]):    
temp = skimage.io.imread('sample.jpg')    
for j in range(temp.shape[2]):        
temp[:,:,j] = temp[:,:,j] * mask[:,:,i]    
plt.figure(figsize=(8,8))    
plt.imshow(temp)      
代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”
代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”
代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

以上即繪制出圖檔各掩膜或對象的操作方法。有許多有趣又使用的用例。圖像分割可以降低計算成本,因為如此一來不需要對整個圖像進行預處理,隻需要預處理分割片段即可。

推斷

下面即Mask R-CNN模型的輸出結果:

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”
代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”
代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”
代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

Mask R-CNN圓滿完成圖像分割任務。太棒了!你已經成功地使用Mask R-CNN模型建立了屬于自己的圖像分割。

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

留言 點贊 關注

我們一起分享AI學習與發展的幹貨

歡迎關注全平台AI垂類自媒體 “讀芯術”

代碼詳解:用Mask R-CNN賦予自動駕駛汽車“火眼金睛”

(添加小編微信:dxsxbb,加入讀者圈,一起讨論最新鮮的人工智能科技哦~)

繼續閱讀