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 语言所撰写的共享函式库,可供其他程式语言呼叫。
图 1、AlexeyAB/darknet 版本的 YOLO 的档案结构图
Day 15 - 说明 YOLO 相关设定 这篇文章中,利用 Joseph/darknet 版本的辨识模型建立一个自建数据集的练习,现在将 AlexeyAV/darknet 相关档案 (darknet, darknet.py, libdarknet.so) 复制到这个文件夹中
图 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
图 3、AlexeyAB.py 执行的文字输出画面
图 4、AlexeyAB.py 执行的图形输出画面
拿原来用命令方式来比较,底下是命令列的执行语法。
./darknet detector test cfg/obj.data cfg/yolov3.cfg weights/yolov3.backup ./labels/00-frame-608x608-0030.jpg -ext_output
图 5、AlexeyAB版本的指令执行的文字输出画面
图 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)
图 7、检验 Python 与 Command 的输出座标
参考资料
- Yolo v4, v3 and v2 for Windows and Linux, https://github.com/AlexeyAB/darknet