【機器學習】如何在PYTHON程式中使用YOLO
Description
2018-10-26
作者:chtseng
前言
Darknet是一套由C語言編寫、專為了YOLO而量身打造的framework,我們在訓練YOLO或預測時,可透過其darknet主程式搭配不同參數以指令模式進行如下的操作:
訓練:
darknet detector train cfg/obj.data cfg/yolov3-tiny.cfg darknet53.conv.74
測試:
darknet detector test cfg.mis/obj.data cfg.mis/tiny-yolo.cfg tiny-yolo.weights images/
若想要透過Python去操控或整合YOLO,雖然官方在python目錄下有提供一個predict image用途的darknet.py,但使用並不方便且功能僅針對圖片的物件偵測,因此,若想要在python程式中整合YOLO,建議使用其它第三方或有心人提供的程式或套件。
個人目前在Python程式中使用YOLO模型的作法有兩種,YOLO3-4-Py以及OpenCV DNN,前者支援GPU可充分發揮GPU的效率,但在純CPU環境下則非常緩慢。後者直接整合於OpenCV方便使用,可惜跟OpenCV一樣尚不支援GPU,不過在純CPU的執行效率倒是比YOLO3-4-Py在CPU上要好很多。因此,如果您有GPU的話,建議選擇YOLO3-4-Py,沒有的話就建議有支援YOLOV3的OpenCV 3.4.3以上版本。
以上面這段剛好三分鐘180秒的影片為例,使用YOLO的pre-trained model(CoCo dataset訓練,可辨識80種物件類型)來辨識影片中的物件,二種方式的執行時間比較如下,使用GPU的YOLO3-4-PY比起單純用CPU的OpenCV DNN快約五倍。
YOLO | Intel i5 CPU | NVidia 1080TX |
OpenCV DNN | 7932.5秒(0.68FPS) | |
YOLO3-4-Py | 1428.9秒(3.78FPS) |
使用OpenCV DNN
可讀取深度學習模型並預測圖片的DNN module,在OpenCV 3.1開始加入contribute套件中,到了3.3版正式成為OpenCV支援的模組之一,支援,到了3.3.1版開始支援YOLO,3.4.3版支援到YOLO V3。
OpenCV 3.3 | Caffe, TensorFlow以及Torch/PyTorch |
OpenCV 3.3.1 | YOLO V1 |
OpenCV 3.4.0 | YOLO V2 |
使用OpenCV DNN module,比較需要注意的是這兩個指令:
- blobFromImage以及blobFromImages:
我們不能直接將imread所讀取的圖片丟進DNN,而必須透過這兩個指令,它們的功能是將圖片讀取後先進行預處理以符合模型所需。所謂的預處理包含了Mean subtraction、scaling、normalization等。(若要深入瞭解建議參考https://www.pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/ 此文)
- 使用create或read來載入模型:
DNN針對不同的深度學習模型,有對應不同的模型名稱command。
create和read這兩種方式皆可載入模型。不過,在3.4版之後,create的方法已經消失,統一改用read取代。
cv2.dnn.createCaffeImporter
cv2.dnn.createTensorFlowImporter
cv2.dnn.createTorchImporter
cv2.dnn.readNetFromCaffe
cv2.dnn.readNetFromTensorFlow
cv2.dnn.readNetFromTorch
cv2.dnn.readhTorchBlob
cv2.dnn.readNetFromDarknet
使用YOLO3-4-Py
YOLO3-4-Py官方頁面是https://github.com/madhawav/YOLO3-4-Py,其功能正如其頁面所介紹的「APython wrapper on Darknet. Compatible with latest YOLO V3.」,坦白說,這是一套非常好用的YOLO python interface。
安裝
安裝前需注意,YOLO3-4-Py與OpenCV 3.4.1版本不相容,必須升級或downgrade到其它版本,否則安裝會失敗。
使用pip安裝
最簡單的安裝方式是透過pip安裝,但可惜這個方法所安裝的yolo34py不會使用到OpenCV相關功能。
- 安裝CPU版本: pip3 install yolo34py
- 安裝GPU版本:pip3 install yolo34py-gpu
從source安裝
官方解釋是由於相容問題因此pip的安裝無啟用OpenCV支援,故建議由source來安裝yolo34py才能啟用OpenCV的支援。
- 加入下方的設定到~/.bashrc(請依您的實際環境修改)
export DARKNET_HOME=/home/digits/works/darknet/
export CUDA_HOME=/usr/local/cuda-9.2/
export PATH=${DARKNET_HOME}:${CUDA_HOME}bin:${PATH}
export DARKNET_HOME=/home/digits/works/darknet/
接著source ~/.bashrc
- 指定支援GPU及OpenCV
export GPU=1
export OPENCV=1
- 在下載的YOLO3-4-PY目錄下,執行
pip install .
把DNN包裝成Python class
為了方便使用,我把讀取YOLO model的OpenCV DNN包裝成了class,以方便在後續的專案中使用。程式放置於https://github.com/ch-tseng/yoloUse.git,您只要clone下來,透過幾行指令便能使用YOLO了,而且還有OpenCV及YOLO-3-4-PY兩種版本可選哦。
OpenCV DNN模組
下方的範例會開啟web camera,然後套用YOLO的pre-trained model來進行實時的物件偵測。如果你沒有GPU的話,使用OpenCV DNN會比YOLO3-4-Py來得快。
在下方讀webcamera實時影像的程式中,只需要黃色字體的三行程式,便能載入YOLO model然後顯示偵測的結果。由於OpenCV DNN模組尚未支援GPU,因此偵測速度並不流暢,但仍是CPU環境下的好選擇。
from yoloOpencv import opencvYOLOimport cv2
import imutils import time yolo = opencvYOLO(modeltype=”yolov3″, objnames=”../darknet/data/coco.names“, weights=”yolov3.weights”, cfg=”../darknet/cfg/yolov3.cfg”) start_time = time.time() if __name__ == “__main__”: VIDEO_IN = cv2.VideoCapture(0) frameID = 0 while True: hasFrame, frame = VIDEO_IN.read() if not hasFrame: print(“Done processing !!!”) print(“— %s seconds —” % (time.time() – start_time)) break yolo.getObject(frame, labelWant=””, drawBox=True, bold=1, textsize=0.6, bcolor=(0,0,255), tcolor=(255,255,255)) print (“Object counts:”, yolo.objCounts) cv2.imshow(“Frame”, imutils.resize(frame, width=850)) k = cv2.waitKey(1) if k == 0xFF & ord(“q”): out.release() break |
就算是有GPU,但限於OpenCV還不支援,因此還是只能用CPU來執行YOLO模型。影片中可發現動作與web camera的影像並不一致,delay的情況相當嚴重。
YOLO3-4-py模組
下方的範例一樣會開啟webcamera,然後套用YOLO的pre-trained model來進行實時的物件偵測。如果你有GPU的話,使用YOLO3-4-Py的速度比起OpenCV DNN快上很多,有實時顯示的效果。但如果沒有GPU,那麼可能速度會比起YOLO3-4-Py來得更慢。
在下方讀webcamera實時影像的程式中,也是僅需要黃色字體的三行程式,便能載入YOLO model然後顯示偵測的結果。如果你安裝的YOLO3-4-py有啟用GPU,那麼會發現它可以即時的處理並顯示webcamera影像。
from yoloPydarknet import pydarknetYOLOimport cv2
import imutils import time yolo = pydarknetYOLO(obdata=”../darknet/cfg/coco.data“, weights=”yolov3.weights”, cfg=”../darknet/cfg/yolov3.cfg”) start_time = time.time() if __name__ == “__main__”: VIDEO_IN = cv2.VideoCapture(0) frameID = 0 while True: hasFrame, frame = VIDEO_IN.read() # Stop the program if reached end of video if not hasFrame: print(“Done processing !!!”) print(“— %s seconds —” % (time.time() – start_time)) break yolo.getObject(frame, labelWant=””, drawBox=True, bold=1, textsize=0.6, bcolor=(0,0,255), tcolor=(255,255,255)) print (“Object counts:”, yolo.objCounts) cv2.imshow(“Frame”, imutils.resize(frame, width=850)) k = cv2.waitKey(1) if k == 0xFF & ord(“q”): out.release() break |
影片中搭配了GPU,速度緩慢的Python在執行YOLO也能如虎添翼,能夠實時的處理web camera畫面並顯示即時影像。
Contact
- CategoryNo Category
Project簡述
- 簡述Darknet是一套由C語言編寫、專為了YOLO而量身打造的framework,我們在訓練YOLO或預測時,可透過其darknet主程式搭配不同參數以指令模式進行如下的操作
- FB Commentshttps://chtseng.wordpress.com/2018/10/08/%E5%A6%82%E4%BD%95%E5%9C%A8python%E7%A8%8B%E5%BC%8F%E4%B8%AD%E4%BD%BF%E7%94%A8yolo/