超快速的端到端實例分割模型,手把手教你用opencv部署Yolact

極市導(dǎo)讀
作為ncnn推理框架里唯一一款做實例分割的模型,yolact也展現(xiàn)出了它的魅力,實現(xiàn)端到端一階段完成實例分割且運行速度快。本文為作者上手編寫的一套使用opencv部署YOLACT做實例分割的程序,程序包含C++和Python兩種版本,附相關(guān)代碼地址。 >>加入極市CV技術(shù)交流群,走在計算機視覺的最前沿
YOLACT,全稱為:You Only Look At CoefficienTs,從標(biāo)題可以看出這個模型的名稱有些致敬YOLO的意思。YOLACT是2019年ICCV會議論文,它是在現(xiàn)有的一階段(one-stage)目標(biāo)檢測模型里添加掩模分支。而經(jīng)典的mask-rcnn是兩階段實例分割模型是在faster-rcnn(兩階段目標(biāo)檢測模型)添加掩模分支,但是在YOLACT里沒有feature roi pooling這個步驟。因而,YOLACT是一個單階段實例分割模型。
起初,我是在知乎上看到Y(jié)OLACT這個模型,文章里說它是端到端一階段完成實例分割,而且運行速度快,并且YOLACT是ncnn(騰訊研發(fā)的手機端高性能神經(jīng)網(wǎng)絡(luò)前向計算框架)推理框架里唯一一款做實例分割的模型。于是我就想著編寫一套程序,使用opencv 部署YOLACT來做實例分割,我把這套程序發(fā)布在github上,程序里包含C ++和Python兩種版本的。
地址是:https://github.com/hpc203/yolact-opencv-dnn-cpp-python
關(guān)于 YOLACT,目前中文互聯(lián)網(wǎng)上的資料多數(shù)是對原始論文的翻譯總結(jié)。簡單講一下YOLACT的網(wǎng)絡(luò)結(jié)構(gòu),如下圖所示

(1). P3~P7送入到Prediction Head分支生成各候選框的類別confidence、 location 和 prototype mask 的 coefficient;
(2). P3送入到Protonet 生成 k 個 prototype mask。在代碼中 k = 32。Prototype mask 和 coefficients 的數(shù)量相等。
然后是后處理操作,得到最右邊的帶有檢測框和mask染色的圖片。下面我將結(jié)合編寫的程序代碼,對這個模型的后處理模塊進行講解。運行python程序,設(shè)斷點查看網(wǎng)絡(luò)輸出,如下圖所示

一共有5種尺度特征圖,在特征圖上的每個像素點會生成3種候選框。因此,最后會生成69693+35353+18183+993+553=19248(你可以在計算器里輸入驗證一下)個候選框。到這時你可以發(fā)現(xiàn),雖然從名稱上看YOLACT是致敬YOLO的,但是使用的是SSD的網(wǎng)絡(luò)結(jié)構(gòu)做目標(biāo)檢測的。
搞清楚了conf_preds的維度的意義后,就可以知道:
conf_preds的維度是(19428,81),表示它包含19428個候選框在80個類別的所有置信度。
loc_data的維度是(19428,4),表示它包含19428個候選框的坐標(biāo)位置(中心點坐標(biāo)(x,y),寬和高,加起來一共4個值)。
mask_data的維度是(19428,32),表示它包含19428個候選框的掩膜系數(shù)(Mask Coefficients)。
proto_data的維度是(138,138,32),它是原型掩膜,它對全部候選框是共享使用的,它與掩膜系數(shù)進行矩陣運算就可以得到最終實例掩膜。
在弄明白了這4個輸出的意義后,接下來的事情就順理成章的展開。首先求conf_preds里的每個候選框在80類里最大類別置信度,得到所屬的類別和置信度,然后根據(jù)過濾掉低于置信度閾值的候選框,使用NMS過濾掉重疊的候選框,經(jīng)過這兩次過濾后剩下的候選框就是最終的目標(biāo)檢測框。這時候可以使用opencv函數(shù)在原圖上畫出目標(biāo)檢測框和所屬類別以及置信度,接著就是計算這些目標(biāo)檢測框的實例掩膜。代碼截圖如下

代碼里令人疑惑的是@符號,在百度搜索Python @,知乎里的回答是在python 3.5以后,@是一個操作符,表示矩陣-向量乘法。但是在代碼里,@的左邊proto_data是形狀為(138,138,32)的三維矩陣,右邊是形狀為(32,1)的矩陣(或者說是列向量)。這時的矩陣計算原理是這樣的,我在草稿紙上畫圖演示,如下圖所示。
輸入Proto_data里一個像素點沿著通道方向的數(shù)值,可以組成一個長度是32的向量,它與長度為32 的mask系數(shù)組成的向量,逐個元素相乘,最后求和得到的數(shù)值(這個過程可以說是向量內(nèi)積)做為輸出圖上的相同位置的像素點的數(shù)值。
還可以這么理解
這時候得到138x138的矩陣特征圖mask,接下來對它做sigmoid變換。然后把它resize到跟原圖一樣高寬大小,這時候的mask就是實例掩膜。接下來遍歷mask里的每個像素點(x,y),如果mask里的像素點(x,y)的值大于0.5,那么就對原圖上該像素點(x,y)的值做調(diào)整。調(diào)整方式是該像素點(x,y)的原始RGB值和目標(biāo)類別的RGB值各取一半求和作為新的像素值。最后顯示原圖,就可以看到目標(biāo)檢測矩形框和類別置信度,還有目標(biāo)實例染色。從COCO數(shù)據(jù)集里隨機選取若干張圖片測試效果。
如下圖所示,左邊的圖是使用opencv做yolact實例分割的可視化結(jié)果。右邊的圖是yolact官方代碼(https://github.com/dbolya/yolact)的可視化結(jié)果。


2020-07-09
2020-07-30
2020-12-22

# 極市原創(chuàng)作者激勵計劃 #

