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 的输出座标

参考资料


<<:  【後转前要多久】# Day06 CSS - Selectors 选取器

>>:  # Day 12 Cache and TLB Flushing Under Linux (四)

Day13 - composition API 初次见面哩贺

今天透过六角的 Vue3 夏令营 Vue 3 Composition API 精髓掌握 初步认识 c...

【第二十七天 - Dijkstra 题目分析】

先简单回顾一下,今天预计分析的题目: 题目连结:https://leetcode.com/prob...

android studio 30天学习笔记 -day 2 -icon

在这次的专案开发有用到vector asset,里面有一些可以应用在专案开发的向量图形,如以下图形:...

连续 30 天 玩玩看 ProtoPie - Day 11

一点开影片要继续看下去...喔喔原来昨天已经看到影片的尾巴了。 讲师跟大家讲了一下谢谢,重新的回顾这...

[Day 22] 针对API的单元测试(二)

我们昨天已经测试了一个Json的API, 那我们今天将测试方法改成这样 public functio...