1. 下載 DeepStream-Yolo, Ultralytics YOLOv8
3. 在 Docker 內, 安裝 DeepStream-Yolo
4. 在 Docker 內, 安裝 Ultralytics YOLOv8
5. 在 Docker 內, 下載,轉換,測試 yolov8s.pt, yolov8s.pt 模型
7. 重新進入 Docker
8. 轉換模型格式為 onnx
9. 在 DeepStream 中測試 onnx 模型
10. 準備自己的圖形資料, PASCAL VOC(LabelImg 產生的 xml) 格式轉換成 txt
import cv2
import os
import random
import re
import xml.etree.ElementTree as ET
import numpy as np
LIGHT_CLASSES_LIST = [
'forward_right',
'others',
'red',
'red_left',
'yellow',
]
def save_false_positives(img_org, iName, xName, tag, classIdx,
clip_x0, clip_y0, clip_x1, clip_y1):
img_new = img_org[clip_y0:clip_y1, clip_x0:clip_x1]
fPath, fName = os.path.split(iName)
fName, fExt = os.path.splitext(fName)
fName = fName + tag + fExt
rndPaths = ['train', 'val', 'test']
rndPath = random.choices(rndPaths, weights=(8,1,1))[0]
iName = os.path.join('/home/datasets/Light/images', rndPath, fName)
cv2.imwrite(iName, img_new)
def convert_box(size, box):
dw, dh = 1. / size[0], 1. / size[1]
x, y, w, h = (box[0] + box[1]) / 2.0 - 1, (box[2] + box[3]) / 2.0 - 1, box[1] - box[0], box[3] - box[2]
return x * dw, y * dh, w * dw, h * dh
def save_file(img_org, iName, xName, tag, classIdx,
p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y,
img_w, img_h, xmin, ymin, xmax, ymax,
clip_x0, clip_y0, clip_x1, clip_y1):
img_new = img_org[clip_y0:clip_y1, clip_x0:clip_x1]
fPath, fName = os.path.split(iName)
fName, fExt = os.path.splitext(fName)
fName = fName + tag + fExt
rndPaths = ['train', 'val', 'test']
rndPath = random.choices(rndPaths, weights=(8,1,1))[0]
iName = os.path.join('/home/datasets/Light/images', rndPath, fName)
cv2.imwrite(iName, img_new)
w = clip_x1 - clip_x0
h = clip_y1 - clip_y0
xmin = xmin - clip_x0
ymin = ymin - clip_y0
xmax = xmax - clip_x0
ymax = ymax - clip_y0
bb = convert_box((w, h), (xmin, xmax, ymin, ymax))
fPath, fName = os.path.split(xName)
fName, fExt = os.path.splitext(fName)
fName = fName + tag + '.txt'
tName = os.path.join('/home/datasets/Light/labels', rndPath, fName)
with open(tName, 'w') as f:
f.write(" ".join([str(a) for a in (classIdx, *bb)]) + '\n')
def gen_img_yolo(iName, xName):
tree = ET.parse(open(xName))
root = tree.getroot()
img_w = int(root.find('size').find('width').text)
img_h = int(root.find('size').find('height').text)
for idx, object in enumerate(root.findall('object')):
name = object.find('name').text
classIdx = LIGHT_CLASSES_LIST.index(name)
#print(classIdx, name)
bndbox = object.find('bndbox')
p0x = int(bndbox.find('p0x').text)
p0y = int(bndbox.find('p0y').text)
p1x = int(bndbox.find('p1x').text)
p1y = int(bndbox.find('p1y').text)
p2x = int(bndbox.find('p2x').text)
p2y = int(bndbox.find('p2y').text)
p3x = int(bndbox.find('p3x').text)
p3y = int(bndbox.find('p3y').text)
xmin = int(bndbox.find('xmin').text)
ymin = int(bndbox.find('ymin').text)
xmax = int(bndbox.find('xmax').text)
ymax = int(bndbox.find('ymax').text)
if xmin != p0x or xmin != p3x or ymin != p0y or ymin != p1y or \
xmax != p1x or xmax != p2x or ymax != p2y or ymax != p3y:
print('error:bndbox', xName)
exit()
if idx > 0:
print('error:object', xName)
exit()
img_org = cv2.imread(iName)
if img_org.shape[0] != img_h or img_org.shape[1] != img_w:
print(img_org.shape, (img_h, img_w))
exit()
img = np.copy(img_org)
clip_x0 = random.randrange(0, int(xmin*0.5))
clip_y0 = random.randrange(0, int(ymin*0.5))
clip_x1 = random.randrange(int(xmax + (img_w-xmax)*0.5), img_w+1)
clip_y1 = random.randrange(int(ymax + (img_h-ymax)*0.5), img_h+1)
save_file(img_org, iName, xName, '', classIdx,
p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y,
img_w, img_h, xmin, ymin, xmax, ymax,
clip_x0, clip_y0, clip_x1, clip_y1)
ratio = (xmax - xmin) / img_w
if ratio < 0.3:
clip_x0 = random.randrange(int(xmin*0.3), int(xmin*0.8))
clip_y0 = random.randrange(int(ymin*0.3), int(ymin*0.8))
clip_x1 = random.randrange(int(xmax + (img_w-xmax)*0.2), int(xmax + (img_w-xmax)*0.7))
clip_y1 = random.randrange(int(ymax + (img_h-ymax)*0.2), int(ymax + (img_h-ymax)*0.7))
save_file(img_org, iName, xName, '_a', classIdx,
p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y,
img_w, img_h, xmin, ymin, xmax, ymax,
clip_x0, clip_y0, clip_x1, clip_y1)
clip_x0 = random.randrange(int(xmin*0.5), int(xmin*0.9))
clip_y0 = random.randrange(int(ymin*0.5), int(ymin*0.9))
clip_x1 = random.randrange(int(xmax + (img_w-xmax)*0.1), int(xmax + (img_w-xmax)*0.5))
clip_y1 = random.randrange(int(ymax + (img_h-ymax)*0.1), int(ymax + (img_h-ymax)*0.5))
save_file(img_org, iName, xName, '_b', classIdx,
p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y,
img_w, img_h, xmin, ymin, xmax, ymax,
clip_x0, clip_y0, clip_x1, clip_y1)
if xmin > (img_w - xmax):
if ymin > (img_h - ymax):
clip_x0 = random.randrange(0, int(xmin*0.8))
clip_y0 = random.randrange(0, int(ymin*0.8))
clip_x1 = random.randrange(int(xmin), int(xmin+(xmax-xmin)*0.8))
clip_y1 = random.randrange(int(ymin), int(ymin+(ymax-ymin)*0.8))
root.remove(object)
save_false_positives(img_org, iName, xName, '_f0', classIdx,
clip_x0, clip_y0, clip_x1, clip_y1)
else:
clip_x0 = random.randrange(0, int(xmin*0.8))
clip_y0 = random.randrange(int(ymin+(ymax-ymin)*0.2), int(ymax))
clip_x1 = random.randrange(int(xmin), int(xmin + (xmax-xmin)*0.8))
clip_y1 = random.randrange(int(ymax+(img_h-ymax)*0.2), img_h)
root.remove(object)
save_false_positives(img_org, iName, xName, '_f1', classIdx,
clip_x0, clip_y0, clip_x1, clip_y1)
else:
if ymin > (img_h - ymax):
clip_x0 = random.randrange(int(xmin+(xmax-xmin)*0.2), int(xmax))
clip_y0 = random.randrange(0, int(ymin*0.8))
clip_x1 = random.randrange(int(xmax + (img_w-xmax)*0.2), img_w)
clip_y1 = random.randrange(int(ymin), int(ymin+(ymax-ymin)*0.8))
root.remove(object)
save_false_positives(img_org, iName, xName, '_f2', classIdx,
clip_x0, clip_y0, clip_x1, clip_y1)
else:
clip_x0 = random.randrange(int(xmin+(xmax-xmin)*0.2), int(xmax))
clip_y0 = random.randrange(int(ymin+(ymax-ymin)*0.2), int(ymax))
clip_x1 = random.randrange(int(xmax + (img_w-xmax)*0.2), img_w)
clip_y1 = random.randrange(int(ymax+(img_h-ymax)*0.2), img_h)
root.remove(object)
save_false_positives(img_org, iName, xName, '_f3', classIdx,
clip_x0, clip_y0, clip_x1, clip_y1)
elif ratio < 0.7:
clip_x0 = random.randrange(int(xmin*0.1), int(xmin*0.7))
clip_y0 = random.randrange(int(ymin*0.1), int(ymin*0.7))
clip_x1 = random.randrange(int(xmax + (img_w-xmax)*0.3), int(xmax + (img_w-xmax)*0.9))
clip_y1 = random.randrange(int(ymax + (img_h-ymax)*0.3), int(ymax + (img_h-ymax)*0.9))
save_file(img_org, iName, xName, '_c', classIdx,
p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y,
img_w, img_h, xmin, ymin, xmax, ymax,
clip_x0, clip_y0, clip_x1, clip_y1)
if xmin > (img_w - xmax):
if ymin > (img_h - ymax):
clip_x0 = random.randrange(0, int(xmin*0.8))
clip_y0 = random.randrange(0, int(ymin*0.8))
clip_x1 = random.randrange(int(xmin), int(xmin+(xmax-xmin)*0.8))
clip_y1 = random.randrange(int(ymin), int(ymin+(ymax-ymin)*0.8))
root.remove(object)
save_false_positives(img_org, iName, xName, '_f4', classIdx,
clip_x0, clip_y0, clip_x1, clip_y1)
else:
clip_x0 = random.randrange(0, int(xmin*0.8))
clip_y0 = random.randrange(int(ymin+(ymax-ymin)*0.2), int(ymax))
clip_x1 = random.randrange(int(xmin), int(xmin + (xmax-xmin)*0.8))
clip_y1 = random.randrange(int(ymax+(img_h-ymax)*0.2), img_h)
root.remove(object)
save_false_positives(img_org, iName, xName, '_f5', classIdx,
clip_x0, clip_y0, clip_x1, clip_y1)
else:
if ymin > (img_h - ymax):
clip_x0 = random.randrange(int(xmin+(xmax-xmin)*0.2), int(xmax))
clip_y0 = random.randrange(0, int(ymin*0.8))
clip_x1 = random.randrange(int(xmax + (img_w-xmax)*0.2), img_w)
clip_y1 = random.randrange(int(ymin), int(ymin+(ymax-ymin)*0.8))
root.remove(object)
save_false_positives(img_org, iName, xName, '_f6', classIdx,
clip_x0, clip_y0, clip_x1, clip_y1)
else:
clip_x0 = random.randrange(int(xmin+(xmax-xmin)*0.2), int(xmax))
clip_y0 = random.randrange(int(ymin+(ymax-ymin)*0.2), int(ymax))
clip_x1 = random.randrange(int(xmax + (img_w-xmax)*0.2), img_w)
clip_y1 = random.randrange(int(ymax+(img_h-ymax)*0.2), img_h)
root.remove(object)
save_false_positives(img_org, iName, xName, '_f7', classIdx,
clip_x0, clip_y0, clip_x1, clip_y1)
elif ratio < 1.0:
pass
return
def recursive_folder(path):
files = os.listdir(path)
files.sort()
for file in files:
fullName = os.path.join(path, file)
if os.path.isfile(fullName):
fPath, fName = os.path.split(fullName)
fName, fExt = os.path.splitext(fName)
if fExt in ('.jpg'):
xPath = fPath + '.xml'
xName = fName + '.xml'
xFName = os.path.join(xPath, xName)
if os.path.isfile(xFName):
gen_img_yolo(fullName, xFName)
else:
print(xFName)
else:
recursive_folder(fullName)
def main():
recursive_folder('/home/Light')
if __name__ == '__main__':
main()
11. 訓練自己的模型
12. 查詢 onnx 模型的輸出輸入層