# 沙灘監測專題報告 ### **組員:陳琮霖, 徐恭亮, 林昱陞** # 製作動機 海灘是度假的理想地點,各種水上活動吸引著許多遊客。我們就讀的中山大學校內就有海灘,因此我們選擇海灘作為主題。 海域安全與環境問題複雜,僅靠救生員難以全面應對。我們希望透過科技即時監測海況,提升安全並預防意外發生,同時保護海洋生態。 # **主要使用技術** ### (一)yolov4 yolo雖然在精確度上不如EfficientDet、ATSS、CenterMask等,但yolo一向主打的是更快的速度,在確保有可接受的精確度後就著重於速度上,使其速度遙遙領先於其他檢測器。 ![image](https://hackmd.io/_uploads/HkvWF4c36.png =60%x) YOLOv4 採用 CSPDarknet53 作為 backbone,其對於目標檢測表現較優,且運算速度更快。 當輸入影像從 608×608 壓縮至 19×19 (y19) 網格,並融合不同的特徵。接著將 SPP(SpatialPyramidPooling) + PAN(PathAggregationNetwork)的多層特徵整合,輸入 Head 進行 bounding box 預測。Head 採用 one-stage 架構,能同時完成物件偵測與辨識,雖然精度略低於 two-stage,但具備更高的運算效率。 ![image](https://hackmd.io/_uploads/r1UXFVqnT.png =80%x) ### (二)物件追蹤 在物件追蹤上主要又分為了三種,**第一個為Central tracker,使用前一個frame和當前的frame的各個bounding box中心點的最近歐式距離當作同一個物件,並賦予其編號,難度較低但當環境複雜且物件較多時就會容易發生switch id或重複算的問題**;其二-deep sort,由Kalman Filter(預測物件在下一個frame的位置)和Hungarian Algorithm(匹配物件的最佳化演算法)組成,再加以外觀訊息讓Hungarian Algorithm和馬氏距離計算,與單純的sort相比減少了45%的id switch問題;最後則是Jointly Detector and Embedding model,這個方法主要就是在訓練模型時將appearence embedding加入網路中一併訓練,在判斷出物件的同時也加入了物件追蹤,**在這次的專題中所採用的方法比較偏向於Central tracker,用中心點在一定的範圍內且是同一個類別則視為同一物件。** # 實作流程及結果 ## (一)水上活動偵測 ![image](https://hackmd.io/_uploads/S1rTtNc2T.png =30%x) 本研究利用labelImg label了1300多張資料及來做訓練,其中約1000張資料來源於kaggle的Boat types recognition,這些資料之中又以sailboat的數量最多,以至於有點影響到最終訓練出來的model,在標記完所有的資料集後,把這些資料集餵進yolov4訓練,取其訓練完的最佳結果,約5300次iteration左右。 ![image](https://hackmd.io/_uploads/SkG2ZIq26.png =80%x) 在訓練出model以後,使用theAIGuysCode[11]提供的判斷+計數程式,算出當前frame分別有什麼船和他們的類別數量,再加以物件追蹤和警訊框來警示救生員異常船隻消失的情況。 物件追蹤 在此研究所使用的物件追蹤主要是以當前frame的中心點和先前frame的四個角做比較,考慮到物件會移動的情況,要判定為同一個物件必須同時滿足: 1. 新的中心點在舊的四角-+20的座標以內的 2. 前後兩個物件類別必須相同 除了判定兩個物件是否為同一物件以外,還要能正確地取消追蹤狀態,而從視窗邊緣離開的屬於正常現象,故條件之中還要再將視窗邊緣的物件移出追蹤名單,故下一個條件為: 3. 刪除從視窗邊緣離開者 ![image](https://hackmd.io/_uploads/Hy86WIq26.png =40%x) 雖然以上三個條件已經可以用來物件追蹤了,但相鄰的物件很容易混淆,造成switch id的狀況,為了降低發生這個狀況的機率,我進一步地將每個boundingbox都賦予其id,用中心點的(x+y)/2當作其id值,同樣的考慮進移動的情況,當前後frame的id在一定範圍內才會被視為同一物件,程式為: last_ID+30>=curr_ID=(mid_x+mid_y)/2>=last_ID-30 雖然還是有switch id的情形發生,但機率上有所降低。 4. 警訊框 藉由物件追蹤的結果來決定是否為異常失蹤,但考慮到有障礙物短暫遮擋或因為某些不明原因而突然判斷不出,採用信心程度來決定消失與否,並排除從視窗邊緣離開者,信心程度的門檻和警示框出現時間都是可以調動的,總結上述條件為: * 使用信心程度,暫定需連續10frame都沒被偵測到 * 沒從視窗邊緣離開 * 框紅框警示,暫定持續7 frame,以示警 ![image](https://hackmd.io/_uploads/SkbfzU53p.png =70%x) 雖然有盡可能地降低switch id的發生率,但只要兩個物件重疊到一起,還是會發生混淆的情況,此外,移動迅速/幅度巨大者也會被歸為兩個不同的物件,資料集的不足及不平衡也使得判斷的結果上不是那麼的理想,時不時偵測不到造成的警訊框更是頻繁讓警訊不被重視,這些都是未來需要解決的問題。 ## (二)海浪偵測 ![image](https://hackmd.io/_uploads/BkfAf8q3a.png =30%x) 本研究針對海浪進行偵測,我們將fps設定為30對影像進行處理,並透過背景分割、影像二質化、雜訊處理、海浪整合與風級計算等一系列步驟完成一套海浪偵測系統。由於影像起初為RGB全彩模式,如圖: ![image](https://hackmd.io/_uploads/B1aJ7Lc26.png =60%x) 我們先將影像進行背景分割,使得原本的RGB圖片轉為灰階圖片,並區出大致海浪浪花(前景)以及海水或是天空(背景) ![image](https://hackmd.io/_uploads/r17bmU5ha.png =60%x) 接著,根據我們自訂的闕值,將進行完背景分割後的影像做影像二值化,如下圖,以利我們後續針對白色區塊(浪花)的部分來做處理。 ![image](https://hackmd.io/_uploads/SJ-dmI5hp.png =60%x) 再來,為了清除影像中的雜訊,我們使用了erosion影像侵蝕,用以移除影像中不必要的小白雜點,並修飾細化影像,搭配delation影像膨脹,將剛剛侵蝕的影像膨脹回來,並連接相近但分開的白色區塊,且若該海域碎浪過多,會增加此膨脹係數,最後再透過median blur中值濾波,定義kernel為5的方形window由左至右,由上至下跑過整張影片,每個pixel由window中的中位數決定,藉此消除雜訊,結果如圖 ![image](https://hackmd.io/_uploads/HkiFXU5hp.png =60%x) 去除雜訊後的二值圖,會有著大大小小的白色區塊,我們計算白色區塊的pixel面積,若大於系統設定值,則將其白色區塊定義為波塊,我們根據這些在影像中抓取到的波塊進行處理,若波塊間彼此距離太相近,或是波塊互為重疊,則將兩者波塊視為相同波塊。 除此之外,由於同個海域的波浪具有斜率相同的特性,而同一個海浪之波塊會經過一條斜率相同的直線,由於這個性質,我們逐一計算波塊之所屬直線,若有其他波塊也經過此直線,則將其認定為相同波塊,用此方法來解決波塊之間有一定距離但仍為相同波浪之整合問題,結果: ![image](https://hackmd.io/_uploads/HkpnX852a.png =60%x) ## (三)沙灘人數監測實作流程: ## ![截圖 2024-02-27 上午2.10.06](https://hackmd.io/_uploads/Hka_E85na.png =50%x) ### 1. 初期想法 原先計畫全身偵測人數,但在人群較集中的照片效果不佳,因為很多人未完整露出全身。於沙灘圖片中,人都較小,很多人在躺或躲在陰影下。因此改為只偵測人的頭部,因為在擁擠場合頭部較容易辨識,這樣應能更準確地偵測每一位人。 ![image](https://hackmd.io/_uploads/BkPaE8c3p.png =80%x) (偵測人體的話僅能找出少數人) ### 2. 更改框選目標 後來改用同樣的圖片繼續框選,框出人體頭部。接著在接下來的實驗中,對於人群數量的監測有著明顯的進步,無論人們是面向正面、反面還是側面都可以被偵測出來。 ![image](https://hackmd.io/_uploads/rkmer893p.png =80%x) (偵測出大量的人) ### 3. 分割圖片以增加精準度 但是在驗證精準度,用肉眼慢慢數圖片中的人時,發現到其實還有一大部分的人都沒有被檢測出來。手算的總人數約821人,但是偵測出來的人數僅359人,精準度僅43.7%,所以就想實驗看看將圖片分割是否能提升精準度。因為切割圖片等同讓各個區塊被放大,如此一來原本因很小而特徵不明顯的人也能更容易被偵測出來。 首先先將圖片利用python的Image將圖片四等分後,再分別偵測四張圖片中的人群。 ![image](https://hackmd.io/_uploads/Sy5zSLc3p.png =50%x)![image](https://hackmd.io/_uploads/S1xXrLqnT.png =50%x) ![image](https://hackmd.io/_uploads/HJ_XBLq3a.png =50%x)![image](https://hackmd.io/_uploads/HyT7BUc2a.png =50%x) (切成四塊並偵測後的圖片) ### 4. 結果 最後再將圖片合起來,並將偵測到的人數也加在一起。 ![image](https://hackmd.io/_uploads/SyAvrI5nT.png =80%x) (最後結果) 可以看出偵測出的人數增加了221人,精準度從43.7%提升到70.6%`。可以看出將圖片進行分割確實可以增加偵測的精準度。接下來我們開始分析四個被分割的圖片,他們個別的精準度大約是多少。 ![image](https://hackmd.io/_uploads/H1N9BUqna.png =80%x) (左上:158/318=49.6%,左下:99/114=85%,右下:72/78=91%,右上:230/332=69%) 結果發現在人群比較不密集的圖片中(右上),如果只偵測人頭,會多偵測出幾個人,但是誤差並不大,精準度都大於80%。 # 結論與感想 在船隻偵測的方面,初步的實現了物件追蹤和示警,儘管因為訓練集的不足導致訓練成效有限,進一步地影響到物件追蹤的半段,使得示警系統效用大減,但只要完善訓練集和改善物件追蹤的方法,就能有效地降低在水上活動的風險,減低救生員的負擔。 而在海浪偵測的方面,透過逐步對波塊的處理,達成了偵測海浪已及風級計算的海上功能,在海域增設此功能,不僅能了解當海域目前狀況,也能在有巨浪時,第一時間通知民眾,減少災害發生。 最後,由沙灘人數偵測得出再處理細小的人群時,只偵測人類頭部與進行圖片分割可以大大的提升精準度,以及對於很小的人可以更準確的找出來,最終也得出最有效率的分割次數。