logo
Loading...

09 - 口罩模型辨識實作 - AIOT 邊緣運算工作坊 - Cupoy

專題實作 - 口罩辨識 - 流程 步驟1:蒐集訓練集資料。 步驟2-3:練習在 Google Colab 上執行 yolo 訓練模型。 步驟4:在 pi 使用 yolo 官方套件測試訓練模型 步驟...

專題實作 - 口罩辨識 - 流程 步驟1:蒐集訓練集資料。 步驟2-3:練習在 Google Colab 上執行 yolo 訓練模型。 步驟4:在 pi 使用 yolo 官方套件測試訓練模型 步驟5:在 pi 執行 OpenCV DNN 呼叫 yolo 模型 專題實作 - 口罩辨識 步驟1:蒐集足夠的 tagging 資料集,口罩辨識資料集,透過網路搜尋,發現有一些可以嘗試練習的資料集,下載資料集之後,進行資料的整理,確定可以做為資料訓練集使用。 步驟2:將資料集進行分類,挑選足夠代表的資料集數量,準備使用 Yolov3 進行訓練,使用程式工具產生 yolov3 訓練集與測試集使用的資料格式。 步驟3:設定 yolov3 訓練時所需要更改的各種設定檔案,準備環境參數與訓練資料路徑,啟動 yolov3 開始進行訓練。 步驟4:將 Yolov3 訓練完成的模型,透過 python 程式載入模型,將範例的影片檔案載入進行辨識,輸出每個畫面中辨識到的物件位置、機率數值。 步驟5:透過 OpenCV DNN 方式即時辨識是否戴口罩,進行前端即時口罩辨識。 步驟 1 蒐集足夠的 tagging 資料集,口罩辨識資料集,透過網路搜尋,發現有一些可以嘗試練習的資料集,下載資料集之後,進行資料的整理,確定可以做為資料訓練集使用。 解答: 搜尋口罩標註資料,可以發現有一些已經準備好的資料集,透過這些過去已經整理好的口罩標注資料集,減少訓練集與測試集資料的準備時間。 網址:https://www.kaggle.com/datasets?search=mask 步驟 1 - 解答 需要訓練一個模型來偵測使用者是否有戴口罩,Dataset 可以從  mouth_mask.7z下載,這是由伊甸基金會所屬的數位資料處理庇護工場所標記,免費開源釋出。 標記格式:PASCAL VOC 圖片總張數:682 張 標記種類三種: good(有正確的戴好口罩) none(臉部露出鼻孔沒有戴好口罩) bad(臉部沒有戴上口罩) 各類別的標記數目: good(有正確的戴好口罩):3,129 個 none(臉部露出鼻孔沒有戴好口罩):126 個 bad(臉部沒有戴上口罩):667 個 使用這個資料庫練習訓練出一個偵測臉部是有戴(好)口罩的模型。 步驟 2 將資料集進行分類,挑選足夠代表的資料集數量,準備使用 yolov3 進行訓練,使用程式工具產生 yolov3 訓練集與測試集使用的資料格式。 解答: 在進行訓練集挑選之前,主要要確定資料的合理性,例如框選的資料範圍,在資料夾中是否確實存在標注的檔案名稱,這些部份需要先加以確定。 步驟2 - 解答 本次練習我們拿這個資料集 100 張圖例作為訓練集。 將每個檔案另外編碼,要注意的規則是影像檔案名稱,其標註檔案即為 txt 副檔名。 準備好資料後,我們可以準備訓練集與測試集列表檔案。 以下是 A001.jpg 的圖像,右邊為標註的資料內容,透過 lableImg 軟體標註的結果。 可以看到影像中有三類的資料類型,分別為 good、bad、none 三個類型,要注意的是編號分別為 0,1,2,類別編號跟標註記得要對應,在後續預測的時候,進行預測的範圍框選時,系統會自動依據框選的物件預測類型,標上類別的名稱。 資料分類名稱的內容順序,就依照資料類型的編號,在此專題中將檔案命名為 obj.names,檔案的內容如下。 將訓練集的資料檔案名稱,編輯成一個列表,這個列表之間可以沒有順序的關聯。 我們打算直接把全部的資料都拿來訓練,所以 train.txt 裡面有 100 個要訓練的影像的檔案名稱。 測試集我們也使用這 100 個檔案,所以很簡單的 train.txt 與 test.txt 可以用同一個檔案內容。 步驟 3 設定 yolov3 訓練時所需要更改的各種設定檔案,準備環境參數與訓練資料路徑,啟動 yolov3 開始進行訓練。 解答: 這個步驟主要能進行 yolov3 分類器的設定,針對訓練集與測試集,設定相對的 yolov3 各種參數設定檔案,同學只要學會使用多分類方式的參數設定,之後就會具備自己設定不同種類類別數量,以及如何準備自己的訓練與測試資料的能力。 步驟 3 - 解答 在這裡說明使用 google colab 進行 yolov3 安裝編譯的方式,因為 google colab 對於 GPU 的支援已經非常成熟,使用 google colab 安裝 yolov3,直接設定 Makefile 內部相關的編譯參數,即可很方便的將支援。 首先我們會啟動一個 colab 環境,然後測試 python3 的 cv2 模組是否已經存在運作的環境中,並且顯示一下 cv2 模組的版本。             import cv2              cv2.__version__ 然後可以用 colab 連接自己的 google Drive,後面的 yolo 訓練步驟會需要事先已經準備好的設定檔案與資料集。 我們會先放置在 google 雲端硬碟的某一個子目錄,因為 google Drive 在 colab 中連接成功時,路徑名稱會是 /content/drive/MyDrive,我們需要點左邊的檔案夾符號進行 google Drive 的連接。 這個步驟最主要的就是安裝 yolo,以及搭配對應的訓練與測試資料集,設定 yolo 參數設定檔,即可進行模型訓練。 搜尋 google,關鍵字為 yolov4 alexeyab。 git clone https://github.com/AlexeyAB/darknet.git 然後切換目錄到 /content/drive/MyDrive/darknet 裡面 在編譯時可能會出現沒有 cmake 套件,因為編譯 darknet 會需要,所以先安裝。 現在可以編譯 darknet 了,使用 make 指令即可編譯。 編譯完成後,我們可以準備開始進行訓練了,在此之前做最後的確認,darknet 能夠正常的啟動執行。 在經驗上在單機與 google colab 上進行 yolo 訓練時,刻意的把單機子目錄也設定成 /content/drive/MyDrive,然後把準備的設定檔跟訓練的資料集都擺在 /content/drive/MyDrive/darknet_train 之下,後續的動作會看起來 google colab 與單機的執行方式完全相同。 接下來我們準備開始進行訓練,yolo 訓練需要準備 4 個設定檔案,分別為(這四個檔案很重要,沒有就不能訓練)                1.  yolo 設定檔案                2.  各種類別標號的名稱檔案                3.  訓練集資料檔案列表                4.  測試集資料檔案列表 要訓練 Yolo,以下 4 個檔案資料一定要準備好 Yolo 資料設定檔案,告訴 yolo 各個訓練要用的檔案位置               a.  設定 類別資料數量               b.  設定 訓練集資料檔案列表之路徑               c.  設定 測試集資料檔案列表之路徑               d.  設定 訓練模型輸出的磁碟之目錄 類別檔案 - 依照類別編號順序,列出各類別編號對應名稱 訓練集資料檔案列表 - 訓練集資料的類別編號與檔案名稱 測試集資料檔案列表 - 測試集資料的類別編號與檔案名稱 最後是依照類別的數量,修改 yolo.cfg 或是 yolo-tiny.cfg 開始進行口罩的資料訓練,先來設定 yolo 的環境檔案。       2.  然後準備口罩訓練集的資料檔案列表。        3.   開始準備口罩測試資料集,設定測試集資料的檔案名稱列表。         4.   然後設定口罩類別編號對應的名稱。         5.   最後是確定測試集資料檔案列表,以及訓練集資料檔案列表的檔案名稱,裡面的每個圖像檔案,都各自有一個標註檔案,副檔案名稱都要是 .txt。         6.   建立訓練模型輸出的路徑 (要對應 obj.data 設定檔案模型輸出) mkdir /content/drive/MyDrive/mask_50/tiny_weights/          7.  最後要設定 yolov3-tiny.cfg 複製並修改 yolov3-tiny.cfg 如下:    Line 3: set batch=24 → 每一次訓練使用 24 張影像    Line 4: set subdivisions=8 → 24 張影像分成 8 次訓練    Line 127: set filters=(classes + 5)*3 → 有 3 個類別,filters=(3+5)*3=24    Line 135: set classes=3 → 辨識共有 3 個類別    Line 171: set filters=(classes + 5)*3 → 有 3 個類別,filters=(3+5)*3=24    Line 177: set classes=3   → 辨識共有 3 個類別 經過上面的 7 個步驟以後,我們可以準備訓練 yolo 了。 參考資料:https://blog.csdn.net/phinoo/article/details/83022101 yolov3-tiny.cfg 檔案設定的地方會長這樣 yolov3-tiny.cfg 的171,177 行會依照資料分類數量設定。 可以進行辨識了,最近要進行辨識前,要準備一個預訓練的 weights,這個檔案可以在https://pjreddie.com/media/files/yolov3-tiny.weights 下載。 將 yolov3-tiny.weights 放在 tiny_weights 的子目錄裡面,這樣就可以開始訓練了,執行以下的命令。可以把訓練的過程輸出到某一個檔案裏面,在這裡將訓練過程輸出到 /content/drive/MyDrive/mask_50/tiny_weights/mask_50_tiny_2020_12_08.logs 檔案中。 !./darknet detector train \ /content/drive/MyDrive/mask_50/cfg/obj.data \ /content/drive/MyDrive/mask_50/cfg/yolov3-tiny.cfg \ /content/drive/MyDrive/mask_50/tiny_weights/yolov3-tiny.weights \ -dont_show -clear 2>&1 |tee -a \ /content/drive/MyDrive/mask_50/tiny_weights/mask_50_tiny_2020_12_08.logs  訓練的過程應該會看到啟動 GPU 以及相關的流程,並且開始各代訓練過程。 如果訓練到某個程度會被系統暫停,這時候可以把訓練輸出某代的模型檔案作為 weights 檔案,放在 darknet 的權重參數,並且將 -clear 的參數不要設定,就可以繼續的往後面的代數訓練了。 步驟 4 將 Yolov3 訓練完成的模型,透過 python 程式載入模型,將範例的影片檔案載入進行辨識,輸出每個畫面中辨識到的物件位置、機率數值。 解答: 此步驟的基礎知識是能夠將訓練好的模型下載回 pi 上面進行預測,此部分最重要的知識是如何把訓練好的模型透過 python 的環境來運作。 透過這樣的過程,之後各種自己訓練好的模型,就能夠自己發展不同情境應用的開發環境,此步驟主要透過 darknet 提供的 python 呼叫環境,因此我們只要學會如何啟動模型進行預測,將預測結果取出作為後續應用。 步驟 4 - 解答 將 yolov4 安裝在 pi 上面。 步驟 4 - 解答 要讓 python 能夠使用 yolov4 的函示庫,要把 Makefile 裡面的 LIBSO=0,變成 LIBSO=1,然後開始編譯。 同時因為 webcam 會用到 OPENCV,所以編譯時候,啟動 OPECV=1,另外需要先安裝 OPENCV 至 PI 的環境中。 執行 apt install python-opencv 安裝。 執行 pip3 install opencv-python 安裝 然後開始編譯 darknet。(需要一小段時間) 編譯完成後,驗證 python3 可以執行 darknet 的函示庫。 透過 darknet_image.py 或 darknet_video.py,把自己訓練好的模型透過這兩個 python 程式來執行。 先把 mask_50 的子目錄,放到 /opt 底下,然後把 /opt/mask_50/cfg/obj.data 內部的內容修改為 pi 上面的執行路徑環境,在 pi 執行時,路徑才會正常。 我們在 tiny_weights 底下準備了一個訓練了 88000 代的 weights 檔案。 在 /opt/darknet 之下,執行底下的指令,確定程式可以執行成功。 python3 darknet_images.py \ --weights /opt/mask_50/tiny_weights/yolov3-tiny_88000.weights \ --config_file /opt/mask_50/cfg/yolov3-tiny.cfg \ --data /opt/mask_50/cfg/obj.data \ --input /opt/mask_50/data/A001.jpg \ --ext_output --dont_show darknet_image.py 執行的方式與 darknet 執行程式相同,可以設定各種參數,例如影像檔案名稱、weights 預測模型、yolov3-tiny 網路參數、yolo 參數檔 obj.data 等。 執行會發現 darknet_image.py 不會產生預測的結果影像檔案,只會產生預測的區域的座標與類別。 如果你想要產生一個預測的影像結果,可以把在 darknet_image.py 最底下的程式碼,改成底下的形式,將 dont_show 沒有設定的時候,改以 cv2.imwrite 輸出影像的結果為 predictions.jpg。 步驟 5 透過 OpenCV DNN 方式即時辨識是否戴口罩,進行前端即時口罩辨識。 解答: 在這個步驟中透過 OpenCV DNN 匯入 yolo 模型,進行即時口罩辨識。 步驟 5 - 解答 本程式命名為 webcam_mask.py load_yolo(): 載入模型 start_webcam(): 啟動webcam攝影機 detect_objects(): 將影像輸入神經網路進行預測 get_box_dimensions() 將預測機率值超過設定的信賴值的區域取出來。 w:辨識區域的寬度 h:辨識區域的高度 X:辨識區域左上角橫座標 Y:辨識區域左上角直座標 [w,h,x,y] 加入 boxes 陣列 conf 加入 confs 陣列中 將 class_id 辨識種類加入 class_ids 的陣列中 透過 NMSBoxes 函數將目標檢測結果,消除重複多餘的框,結果儲存在 indexes 內。 將 boxes 裡面有的辨識區域畫出來,可以依此觀察辨識區域的位置。 最後將辨識的區域左上角區域點(x,y)以及區域的寬高(w,h)傳送至 pi 本身的 flask 執行的 web server。 最後透過 webcam_detect() 函式,啟動攝影機,開始讀取影像、偵測物體、取得物件預測結果的區域、將預測類別標籤畫在影像上,進入無窮迴圈的狀態,直到程式執行結束為止。 執行 python3 webcam_mask.py 前面 python3 webcam_mask.py,啟動了 webcam,載入了口罩辨識模型。 會看到不斷的辨識出有戴口罩或者是沒有口罩的狀態,並且會將辨識出來的結果剪下影像儲存至 pi 的 sdcard 上面。 在這個範例中,將 webcam_mask.py 與 mask_flask.py 都放在 /opt/webcam_mask 子目錄底下,因此會看到 /opt/webcam_mask 子目錄底下會出現辨識到的人臉結果影像。 可以抓取依照檔案名稱的影像。底下可以看到口罩辨識系統依序拍下的檔案名稱。 專題實作 - 完成 恭喜你完成了。 相信經過這個過程,應該學會了各個系統獨立測試的流程。 每個部分其實都可以當成一個獨立的部分驗證,然後再把這些部分組合起來。