【機器學習】如何在PYTHON程式中使用YOLO

Description

Description
作者: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,比較需要注意的是這兩個指令:

  1. blobFromImage以及blobFromImages:

我們不能直接將imread所讀取的圖片丟進DNN,而必須透過這兩個指令,它們的功能是將圖片讀取後先進行預處理以符合模型所需。所謂的預處理包含了Mean subtraction、scaling、normalization等。(若要深入瞭解建議參考https://www.pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/ 此文)

  1. 使用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的支援。

  1. 加入下方的設定到~/.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

  1. 指定支援GPU及OpenCV

export GPU=1

export OPENCV=1

  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畫面並顯示即時影像。

Latest posts by ChengChung Tseng (see all)

    Contact

    Contact
    • Category
      No Category

    Project簡述

    Project簡述
    • 簡述
      Darknet是一套由C語言編寫、專為了YOLO而量身打造的framework,我們在訓練YOLO或預測時,可透過其darknet主程式搭配不同參數以指令模式進行如下的操作
    • 作者
      chtseng
    • FB Comments
      https://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/

    您的姓名 〈需填寫〉

    您的電子郵件信箱 〈需填寫〉

    主旨

    您的信件內容