---
# System prepended metadata

title: 大學專題製作-沙灘監測

---

# 沙灘監測專題報告 

### **組員：陳琮霖, 徐恭亮, 林昱陞**

# 製作動機
海灘是度假的理想地點，各種水上活動吸引著許多遊客。我們就讀的中山大學校內就有海灘，因此我們選擇海灘作為主題。

海域安全與環境問題複雜，僅靠救生員難以全面應對。我們希望透過科技即時監測海況，提升安全並預防意外發生，同時保護海洋生態。



# **主要使用技術**
### (一)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%。

# 結論與感想
在船隻偵測的方面，初步的實現了物件追蹤和示警，儘管因為訓練集的不足導致訓練成效有限，進一步地影響到物件追蹤的半段，使得示警系統效用大減，但只要完善訓練集和改善物件追蹤的方法，就能有效地降低在水上活動的風險，減低救生員的負擔。

而在海浪偵測的方面，透過逐步對波塊的處理，達成了偵測海浪已及風級計算的海上功能，在海域增設此功能，不僅能了解當海域目前狀況，也能在有巨浪時，第一時間通知民眾，減少災害發生。

最後，由沙灘人數偵測得出再處理細小的人群時，只偵測人類頭部與進行圖片分割可以大大的提升精準度，以及對於很小的人可以更準確的找出來，最終也得出最有效率的分割次數。
