INTRODUCTION

一、 前言

這個專題主要分成兩大部分,因為若直接把變形過的全景影像拿去訓練會降低模型的學習效果,所以第一部分我們要做的是把360全景鏡頭的影像轉換成cubic和equirectangular的影像。我們用的360鏡頭是LUNA公司提供的,實際上它是由兩顆超廣角的魚眼鏡頭組成(FOV 190°),我們用Python撰寫影像演算法將其得到校正後+x、-x、+y、-y、+z、-z六個面的影像。

第二部分是把前面得到的cubic map影像(或影片)做real-time object detection (not tracking),我們用tensorflow去實現 YOLO model來達到我們的需求,YOLO將整張圖片切成若干不同大小的區域,然後每個區域隨機預測各自的bounding boxes和概率,利用這種方法,比起傳統的CNN神經網路快非常多。

二、原理分析與系統設計

2.2 原理分析

1. 360 Transformer

我們從LUNA讀取的圖片是dual fisheye,也就是由兩顆視角190度fisheye鏡頭所拍下來的圖片,放在同一個圖片,如圖三所示。而要將dual fisheye的圖片,轉換成cubic map的樣子,以方便我們使用yolo model去做detect的動作。

而所謂的cubic map,就是將360度的全景影像,轉換成由「上、下、左、右、前、後」六個面所組成的立方體,並將此立方體展開,如圖四所示。而轉換成cubic map是因為原本的dual fisheye的圖片,除了圓心附近的區域外,都有著不同程度的變形,而隨著與邊界的距離越近,變形也便得越加嚴重。而對於yolo model而言,變形的圖片就代表著在detect的時候,準確率的下降。而轉換成cubic map之後,對於圖片變形的問題,尤其是在圖片邊界的地方,將會有所改善。

而由dual fisheye到cubic map的轉換方式,我們使用「cube mapping」這種轉換方式,如圖五所示。這種轉換方式藉由觀察dual fisheye上每個pixel的向量,即可進行轉換。而接下來將會介紹cube mapping的實做過程。

(1) rotation

由於我們從LUNA上讀到的圖片是dual fisheye,而做cube mapping需要的是一個球體。因此,我們首先需要把dual fisheye轉換成球體,而最簡單的方式就是把dual fisheye image往進入圖片的方向對折,即可得到一個球體。而對折這個動作,其實就是旋轉,也就是rotation的意思。而我們是使用四元數這個概念來做旋轉。

(2) uv mapping

在做完旋轉之後,我們將這個球體從3D轉換成2D,主要是為了降低維度以節省運算量,以及將球體的點投影到立方體的一個面上。

簡單來說,就是選擇球體的其中一部份,其中這個部份會投影到立方體上的一個面,假設這個面叫做A。而球體的中心到A的重心會有一個向量,我們將這個向量叫做V,且球體中心到球體表面上選取的一部分上的任意一點的向量叫做V’,那我們可以藉由V跟V’得到兩者在某一維度的夾角為θ。而θ跟另外兩個維度,即可代表原本3D系統中各點的座標。

(3) get weight

所謂的get weight,其實就是在立方體的一個面上,求各點到面的邊界的距離。而求取各點的距離的原因,為因為越接近fisheye image的邊界,變形也就更加的嚴重。而在取得各點的weight之前,必須先得知有關於各點與面的重心之間的距離,看看是否在我們想要的面上。而這個問題的答案,我們稱之為各點的mask。而mask的值為True 或False。

而有了各點的mask之後,我們就可以確定我們的weight為一個不小於0的數,換句話說,我們得到的weight都會是有意義的。接下來我們會將各點的weight相加,並且將各點的weight去除以weight的總和,這樣得到的值就是各點的weight的norm。

(4) rendering

在知道球體上各點如何投影到立方體上之後,我們就可以把球體上各點的資訊(RGB三原色)放到立方體的面上。

其中,out_size代表著立方體的邊長。vec0是一個element都是out_size/2的array; vec1是每個element都出現 out_size次後再加1; vec2重複cvec這個array out_size次的array。其中,vec0、vec1、vec2分別代表3D空間中X、Y、Z的值。而對於cubic map的六個面而言,每一個面所被投影到的東西是來自於dual fisheye image所形成的球體中的一部分。換句話說,只要給定3D空間中X、Y、Z的範圍,然後把這個範圍裡面的每個點去做uv mapping,並且取得它們的weight的norm,最後再把dual fisheye image上的點投影到立方體的面上,就可以完成cubic map了。

2. YOLO (You Only Look Once)

由於我們的專題希望達成real-time streaming,所以我們選用了2016年CVPR上的論文:You Only Look Once (YOLO): Unified, Real-Time Object Detection來實作達成我們的需求,雖然他是Open source的,但因為他是用c語言寫,而我們的360° image transformer是用Python寫的,所以我們改用tensorflow去實作YOLO。

(1) YOLO簡介

目前主流的object detection方法都把問題當作分類問題,如:R-CNN、fast R-CNN等,而YOLO將檢測的方法當作一個回歸問題(regression problem),比起Faster R-CNN需要兩個網絡RPN和Fast R-CNN,YOLO僅僅透過一個neural network就可以得到物件的bounding boxes和每個bounding box分類的概率,再運算上做了很大的優化,使其可以達到45fps的real-time object detection,mAP的表現也與原始的R-CNN差不多。

YOLO和faster RCNN一樣用整張圖做為輸入,然後分成SxS個網格(grid cell),若某個object的位置落在某個網格裡面,就由該網格負責那個object的檢測

同時,每個網格還要負責(隨機)預測B個bounding boxes的資訊(x, y, w, h)、一個confidence值以及類別訊息(C類),confidence代表model對於這個grid cell中預測是否含有物體的置信度,以及是這個物體的概率有多少

training的方法是採用隨機梯度下降法以及為了避免overfitting使用dropout的方法,在test的時候,將每個網格預測的類別訊息與bounding box預測的Confidence相乘就可以得到每個bounding box的class-specific confidence分數,再經過閥值的過濾,然後執行非極大值抑制(NMS)處理後得到最終檢測結果

(2) LOSS function

YOLO在誤差計算上全部採用了sum-squared error loss去計算,loss function公式如下,前兩項是bounding box位置的預測,第三(四)項是有(無)object的bounding bod confidence值的預測,最後一項則是類別的預測

另外,YOLO除了在最後一層fully-connected layer使用了線性的activative function外,其他層都是使用leaky ReLU進行激活。

三、實驗結果

實測YOLO real-time object detection的在GTX 1080 Ti上執行可以速度達到約50fps,在VOC 2007+2012的訓練集上的精度可以達到70 mAP;簡易版的tiny YOLO model,可以達到150fps,50 mAP。但受限於360 transformer的轉換效率,在高畫質的輸出還沒有辦法做到real-time streaming。

四、結論

1. 關於360 transformer的部分,其優點是可以選擇要觀察cubic map的其中幾面,但是缺點就是其選擇的面數越多,計算量也跟著增加。而關於此演算法的效率,也有其改善的空間。目標是希望在畫質不低的情況下(output size 至少為512*512)可以真正的實現real-time。但是就轉換過後的結果來看,其實這個transformer的效果是可以接受的。

2. 關於LUNA的部分,也有幾個問題: (1)對於鄰近物體的判別:如果兩個Objects出現在同一個grid cell中,模型只能預測一個物體,對於小物體或太過靠近的物體檢測上會出問題; (2) 由於loss function使用了sum-squared error,在定位誤差上影響很大; (3) 對於一些特殊長寬比例的物體不易辨別。代表在model的選擇上,其實也還有可以改善的空間。

五、參考文獻

[1] Paul Bourke。Converting dual fisheye images into a spherical (equirectangular) projection

[2] https://pjreddie.com/darknet/yolo/ YOLO:Real-Time Object Detection 2017/8/31

[3] Alexander C. Utter。https://github.com/ooterness/DualFisheye/blob/master/fisheye.py。 2017/3/6

[4] Joseph Redmon, Ali Farhadi。YOLO9000: Better, Faster, Stronger。

六、計劃管理與團隊合作方式

1.

(一) 計劃管理方面: 我們一開始的計畫其實是打算做360 VR影像的stitching,由於下學期實驗室採購了LUNA的全景鏡頭,它的APP已經把stitching做的蠻完美了,可是他沒有open source且linux系統上的API尚未釋出無法搭載到實驗室的機器人上,所以我們就決定自己寫一套API並和深度學習結合。 進度規劃的話前三個月我們主要在paper study,看一些standford deep learning和CV的課程,三下開始進行實作,專題研究過程看paper遇到不懂的地方我們會自己先討論,不懂的地方每週meeting時再和指導我們的學長討論,孫民老師也提供我們很多資源和幫助,我們在研究方向和實作上遇到困難時都會隨時透過臉書社團和email給予協助,也會鼓勵我們參加workshop。

2.

(二) 團隊合作方面: 我們的分工蠻明確的,除了每週跟學長的meeting,我們平常兩個人會花2~3天開讀書會討論,分配看不同的paper,看懂之後在告訴對方自己負責的部分(360 transform的部分主要是崇誌負責,YOLO是舜昌負責)。下學期開始進行實作也是,我們會參考一些網路上的code(Github),一個人負責讀code一個人負責畫演算法的架構圖,最後再整合,我覺得我們這樣的分工模式還蠻有效率的。


Fig. 1


Fig. 2


Fig. 3


Fig. 4


Fig. 5

心得感想

Computer Vision和AI之餘我們都是沒接觸過的領域,從一開始看Stanford的機器學習線上課程,學習CNN、RNN的概念;自學Python和OpenCV,到現在能完成一個專題,真的很感謝孫民老師對我們的悉心指導以及VSLab學長們的帶領。

在整個專題研究的過程中,我們學到了研究的方法。如何訂定一個題目,然後隨著進度不斷去修改、調整。遇到瓶頸時如何查詢有用的資料,想辦法突破,這些都是只有實際動手去做了之後才知道的珍貴經驗。未來我們也會秉持這樣的研究精神,在CV和AI領域繼續鑽研,讓自己變的更強。