iT邦幫忙

2021 iThome 鐵人賽

DAY 21
1
AI & Data

觀賞魚辨識的YOLO全餐系列 第 21

Day 21 - 嵌入 AlexeyAB/darknet 的 Python

Day 21 - 嵌入 AlexeyAB/darknet 的 Python

如同先前的 Joseph/darknet 一樣, AlexeyAB/darknet 版本也提供了 Python 的介面,可以讓 Python 的開發人員直接調用,好方便結合原有的 Python 代碼,比較不同的是,他並沒有特別放在 python 這個目錄,而是直接放在根目錄裡,在 Day 20 - 重新檢視 mAP, F1, IoU, Precision-Recall 精準度 這篇文章有詳細介紹 AlexeyAB/darknet 的檔案結構,下圖是安裝 AlexeyAB/darknet 版本的 YOLO 的檔案結構圖,,這邊就只針對需要用到的部份加以說明:

  • darknet: AlexeyAB/darknet 的主要執行檔。
  • darknet_image.py, darknet.py, darknet_video.py:透過呼叫 libdarknet.so ,可以在 Python 中直接調用 AlexeyAB/darknet 的一些主要功能,如訓練、測試、載入網路結構等。
  • libdarknet.so: AlexeyAB/darknet 使用 c 語言所撰寫的共享函式庫,可供其他程式語言呼叫。

https://ithelp.ithome.com.tw/upload/images/20210921/201295105H6sacs3BO.png
圖 1、AlexeyAB/darknet 版本的 YOLO 的檔案結構圖

Day 15 - 說明 YOLO 相關設定 這篇文章中,利用 Joseph/darknet 版本的辨識模型建立一個自建數據集的練習,現在將 AlexeyAV/darknet 相關檔案 (darknet, darknet.py, libdarknet.so) 複製到這個文件夾中

https://ithelp.ithome.com.tw/upload/images/20210921/201295102YkP92L7pL.png
圖 2、自建數據集的影像辨識文件夾,引入 AlexeyAB/darknet

接著建立一個檔案,匯入 darknet.py,接著指定相關組態就可以了,yolov3.cfg,obj.data 這兩個檔案在 Day 15 - 說明 YOLO 相關設定 這篇文章有詳細說明,yolov3.backup 則是在 Day 16 - 進行影像辨識訓練 這篇文章訓練生成的。

AlexeyABYolo.py

import cv2
import darknet
import time

def image_detection(image_path, network, class_names, class_colors, thresh):
    width = darknet.network_width(network)
    height = darknet.network_height(network)
    darknet_image = darknet.make_image(width, height, 3)

    image = cv2.imread(image_path)
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image_resized = cv2.resize(image_rgb, (width, height),
                               interpolation=cv2.INTER_LINEAR)

    darknet.copy_image_from_bytes(darknet_image, image_resized.tobytes())
    detections = darknet.detect_image(network, class_names, darknet_image, thresh=thresh)
    darknet.free_image(darknet_image)
    image = darknet.draw_boxes(detections, image_resized, class_colors)
    return cv2.cvtColor(image, cv2.COLOR_BGR2RGB), detections

# 指定網路結構配置檔 yolov3.cfg,自建數據集設定檔 obj.data,事先訓練好的權重檔 yolov3.backup
network, class_names, class_colors = darknet.load_network(
    "./cfg/yolov3.cfg",
    "./cfg/obj.data",
    "./weights/yolov3.backup",
    1
)

prev_time = time.time() # 用來計算辨識一張圖片的時間
print('predicting...', prev_time)
# 進行影像辨識,回傳畫出方塊框的圖片以及辨識結果,辨識結果包含標籤、置信度以及方塊框的座標
image, detections = image_detection(
        './labels/00-frame-608x608-0030.jpg', network, class_names, class_colors, 0.25
        )
# 印出標籤、置信度以及方塊框的座標
darknet.print_detections(detections, '--ext_output')
# 顯示辨識時間
print((time.time() - prev_time))
# 將結果圖片寫成檔案 result.jpg
cv2.imwrite('result.jpg', image)

運行之前需先安裝 OpenCV,因為這個程式會用到,畫面如下所示,辨識出三個物件,後面有有列出左上角座標以及長寬,時間約 0.566 秒。

pip3 install opencv-python
python3 AlexeyAB.py

https://ithelp.ithome.com.tw/upload/images/20210921/20129510mlzy6aEXKR.png
圖 3、AlexeyAB.py 執行的文字輸出畫面

https://ithelp.ithome.com.tw/upload/images/20210921/20129510opPrXkHvFh.png
圖 4、AlexeyAB.py 執行的圖形輸出畫面

拿原來用命令方式來比較,底下是命令列的執行語法。

./darknet detector test cfg/obj.data cfg/yolov3.cfg weights/yolov3.backup ./labels/00-frame-608x608-0030.jpg -ext_output

https://ithelp.ithome.com.tw/upload/images/20210921/20129510Zld2mDb4p0.png
圖 5、AlexeyAB版本的指令執行的文字輸出畫面

https://ithelp.ithome.com.tw/upload/images/20210921/20129510a0QnX2fZmu.png
圖 6、AlexeyAB版本的指令執行的圖形輸出畫面

發現邊是的物件內容是一樣,但置信度的部份,使用 Python 的部份沒有在小數點後三位四捨五入,所以結果是 99.22%, 99.94%, 99.97%,而指令部分則是 99%, 100%, 100%;辨識時間上也差不多,指令執行約 0.558 秒,而Python部分則是 0.566 秒;最奇怪的是 bbox 的資料不一樣,下表列出使用 Python 與使用 command的方塊框座標比較表,直接觀看結果圖片,方塊框是一樣的,可以發現 Python 取的是中心點的座標,而 Command 取的是左上角座標。

表 1. 使用 Python 與使用 Command 的方塊框座標比較表

  left_x top_y width height
Python 102 420 171 93
Command 16 374 171 93

以下為使用 Python 與 Command 的輸出座標內容。

# using Pyhon
Altolamprologuscompressiceps: 99.22%    (left_x: 102   top_y:  420   width:   171   height:  93)
Altolamprologuscompressiceps: 99.94%    (left_x: 235   top_y:  373   width:   86   height:  51)
Altolamprologuscompressiceps: 99.97%    (left_x: 311   top_y:  400   width:   147   height:  77)

# using Command
Altolamprologuscompressiceps: 99%	(left_x:   16   top_y:  374   width:  171   height:   93)
Altolamprologuscompressiceps: 100%	(left_x:  192   top_y:  348   width:   86   height:   51)
Altolamprologuscompressiceps: 100%	(left_x:  238   top_y:  361   width:  147   height:   77)       

使用下列程式根據 Command 所提供的座標畫出第一個物件的方塊框,圖型如下所示。

DrawCoord.py

import cv2

inputImgPath = '../labels/00-frame-608x608-0030.jpg'
outputImgPath = '../image/00-frame-608x608-0030-1.jpg'
img_w= img_h = 608
cv2image = cv2.imread(inputImgPath)

# Altolamprologuscompressiceps: 99%	(left_x:   16   top_y:  374   width:  171   height:   93)
min_x, min_y, max_x, max_y = 16,374,16+171,374+93
cv2.rectangle(cv2image, (int(min_x),int(min_y)), (int(max_x),int(max_y)), (0,255,255), 2)
cv2.imwrite(r'{}'.format(outputImgPath), cv2image)

https://ithelp.ithome.com.tw/upload/images/20210921/20129510lK9dUgmK9e.png
圖 7、檢驗 Python 與 Command 的輸出座標

參考資料


上一篇
Day 20 - 重新檢視 mAP, F1, IoU, Precision-Recall 精準度
下一篇
Day 22 - Django + YOLO 後台整合應用
系列文
觀賞魚辨識的YOLO全餐38

1 則留言

0
q122858
iT邦新手 5 級 ‧ 2021-10-08 13:15:29

您好:
想請問一下我想要辨識的是影片不是圖片,偵測的方法是需要自己完成還是有什麼資料可以參考呢?感謝您的回答

你可以直接參考這個網址,YOLO本身就擅長於影片即時辨識。
https://ithelp.ithome.com.tw/upload/images/20211009/20129510tGdqA9kFan.png
這是實驗數據,在效能表現跟精準度都有很好的數字。
Yolo v4, v3 and v2 for Windows and Linux, https://github.com/AlexeyAB/darknet

我要留言

立即登入留言