Вы находитесь на странице: 1из 13

Практика №1 Портирование модели Yolo_v7 на

RK3588

Описание задачи
Для выполнения практического задания необходимо написать веб приложение,
выводящее в окно браузера изображение с камеры, и детектирующие объекты на
изображении, с помощью представленной модели.

В окне браузера вы должны получить подобный результат:

Для выполнения задачи потребуется:


1) Персональный компьютер с установленной Ubuntu 20.04 LTS ( можно
использовать любой другой дистрибутив, но установка пакетов описана именно
для ubuntu)
2) Одноплатный компьютер Orange Pi 5
3) micro SD карта
4) USB картридер
5) картридер
6) USB камера совместимая с V4L драйвером
7) Роутер с как минимум двумя портами для ПК и одноплатного компьютера и
развернутым на нем DHCP и доступом к интернету.
8) Пачкорды
9) Монитор
10) Клавиатура
11) Мышь

Вместо роутера(пункт 6) можно любым другим образом объединить одноплатный


компьютер и персональный компьютер студента в локальную сеть с доступом к
интернету.

Подробные ссылки на необходимые камеру и одноплатный компьютер представлены в


таблице в приложении.

Настройка перед работой

Установка операционной системы на одноплатник

Подключите свой ПК и Orange Pi к роутеру.


Подключите камеру, монитор, клавиатуру и мышь к Orange Pi

Установку образа будем производить с помощью утилиты Balena etcher.


Скачайте .deb пакет последнего релиза программы
https://github.com/balena-io/etcher/releases/

Перейдите в папку со скачанным пакетом и установите:

cd/<Download_Folder>
sudo apt install ./balena-etcher_******_amd64.deb

Запуск осуществляется командой

balena-etcher

Скачайте образ операционной системы для Orange pi 5

https://drive.google.com/drive/folders/1i5zQOg1GIA4_VNGikFl2nPM0Y2MBw2M0

В этой работе мы будем использовать дистрибутив ubuntu focal с окружением xfce

Запустите программу balena-etcher и выберите скачанный образ:


Подключите USB картридер с SD картой выберите свою карту и нажмите Flash!
После того как вы прошили образ на SD карту извлеките ее из картридера и вставьте в
разъем для sd карты в Orange Pi

Подключите питание к Orange Pi

После загрузки запустите терминал командной строки

Для начала обновим программное обеспечение

sudo apt update


sudo apt upgrade

Теперь проверим свой адрес в сети


ifconfig

Вы получите примерно следующее:

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500


inet 192.168.31.31 netmask 255.255.255.0 broadcast 192.168.31.255
inet6 fe80::a0d2:dbc7:dc34:4b67 prefixlen 64 scopeid 0x20<link>
ether 2e:67:a6:ce:a4:ba txqueuelen 1000 (Ethernet)
RX packets 1381021 bytes 1351236603 (1.3 GB)
RX errors 0 dropped 13 overruns 0 frame 0
TX packets 892517 bytes 2830734510 (2.8 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 85

В моем примере адрес Orange Pi 192.168.31.31

Проверьте подключена ли камера

sudo apt-get install v4l-utils


v4l2-ctl --list-devices

Вы получите примерно следующее:

USB 2.0 Camera: USB Camera (usb-xhci-hcd.9.auto-1):


/dev/video0
/dev/video1
/dev/media0

В моем примере камера подключена в /dev/video0


Настройка системы Orange Pi

Установим драйвера для NPU

git clone https://github.com/rockchip-linux/rknpu2.git


git clone https://github.com/rockchip-linux/rknn-toolkit2

cp rknpu2/runtime/RK3588/Linux/rknn_server/aarch64/usr/bin/restart_rknn.sh
/usr/bin
$ cp rknpu2/runtime/RK3588/Linux/rknn_server/aarch64/usr/bin/start_rknn.sh
/usr/bin
cp rknpu2/runtime/RK3588/Linux/rknn_server/aarch64/usr/bin/rknn_server /usr/bin
cp rknpu2/runtime/RK3588/Linux/librknn_api/aarch64/librknn_api.so /usr/lib
cp rknpu2/runtime/RK3588/Linux/librknn_api/aarch64/librknnrt.so /usr/lib
restart_rknn.sh

pip3 install
rknn-toolkit2/rknn_toolkit_lite2/rknn_toolkit_lite2-1.5.2-cp38-cp38-linux_aarch6
4.whl
pip3 install flask
pip3 install opencv-python
pip3 install numpy

Настройка ssh

sudo apt install openssh-server


sudo systemctl enable --now ssh.service

Все необходимые пакеты установлены и настроены

Веб приложение

Создадим простой flask сервер для видеостриминга

Используем для этого репозиторий

git clone https://github.com/NakulLakhotia/Live-Streaming-using-OpenCV-Flask.git

Отредактируем код приложения:

$ nano Live-Streaming-using-OpenCV-Flask/app.py

Закомментируем захват видео с камеры


#camera =
cv2.VideoCapture('rtsp://freja.hiof.no:1935/rtplive/_definst_/hessdalen03.stream
')

Добавим захват кадров в функцию def gen_frames():

def gen_frames(): # generate frame by frame from camera


camera = cv2.VideoCapture(0)
while True:
# Capture frame-by-frame
success, frame = camera.read() # read the camera frame
if not success:
break
else:
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame +
b'\r\n')

Заменим адрес и порт для веб сервера:


if __name__ == '__main__':
app.run(host='192.168.31.31:8080',debug=True)

Запустите скрипт

python3 app.py

откройте в браузере

http://192.168.31.31:8080/

Вы получите следующее:
Веб приложение работает

Подготовка ПК для портирования модели

Настроим виртуальную среду python на вашем ПК

sudo apt update


sudo apt upgrade
sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt update
sudo apt install python3.8
sudo apt install python3.8-venv
python3.8 -m venv env-3.8
source env-3.8/bin/activate

Портирование модели yolo

Теперь, когда вы настроили среду, воспользуемся форком yolo_v7 для портирования


модели

Воспользуемся репозиторием
https://github.com/laitathei/YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection/tree/main

В репозитории уже есть предобученая модель yolo_v7 из форка


https://github.com/WongKinYiu/yolov7/tree/84932d70fb9e2932d0a70e4a1f02a1d6dd1dd6ca

Проследуем инструкции из репозитория:

git clone --recursive


https://github.com/laitathei/YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection.git

Скачайте и установите пакеты: torch: 1.10.1+cu102 torchvision: 0.11.2+cu102


https://download.pytorch.org/whl/cu102/torch/
https://download.pytorch.org/whl/cu102/torchvision/

установите onnx

pip3 install onnx==1.10.0


pip3 install onnxruntime==1.10.0

Установите зависимости yolo


pip3 install -r
YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection/yolov7/requirements.txt

Конверсия модели в формат ONNX

python3 pytorch2onnx.py --weights ./model/yolov7-tiny.pt --simplify --img-size


480 640 --max-wh 640 --topk-all 100 --end2end --grid

Установим пакет конверсии в RKNN

pip3 install
YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection/rknn-toolkit2/packages/rknn_toolkit2
-1.5.0+1fa95b5c-cp38-cp38-linux_x86_64.whl

Теперь необходимо изменить структуру модели, для чего воспользуемся приложением


https://github.com/ZhangGe6/onnx-modifier/tree/2333f63dc74f5cbe28adc4fe68a914382b17
2077

pip3 install -r onnx-modifier/requirements.txt


pip3 install onnx==1.10.0
python3 onnx-modifier/app.py

Перейдите в браузере http://127.0.0.1:5000/ в приложении откройте модель


./YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection/model/yolov7-tiny-480-640.onnx

Удалите эту часть в конце модели


Добавьте выход к ячейке concat
Сохраните полученную модель

Замените модель в папке


./YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection/model/yolov7-tiny-480-640.onn на
измененную

Сконвертируйте модель в RKNN

python3 onnx2rknn_step1.py
python3 onnx2rknn_step2.py

Теперь необходимо скопировать модель на одноплатный компьютер:

scp -r YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection/model/
orangepi@192.168.31.31:/home/orangepi/Live-Streaming-using-OpenCV-Flask/
scp -r YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection/config/
orangepi@192.168.31.31:/home/orangepi/Live-Streaming-using-OpenCV-Flask/
scp -r YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection/dataset/
orangepi@192.168.31.31:/home/orangepi/Live-Streaming-using-OpenCV-Flask/
scp -r YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection/result/
orangepi@192.168.31.31:/home/orangepi/Live-Streaming-using-OpenCV-Flask/
scp YOLOv7-ONNX-RKNN-HORIZON-TensorRT-Detection/util.py
orangepi@192.168.31.31:/home/orangepi/Live-Streaming-using-OpenCV-Flask/

Если нет возможности скопировать через ssh, воспользуйтесь usb flash.

Теперь добавим инференс модели в наше веб приложение. Отредактируйте файл на


Orange Pi: /home/Live-Streaming-using-OpenCV-Flask/app.py

from flask import Flask, render_template, Response


import os, cv2, time, numpy as np
from util import *
from rknnlite.api import RKNNLite

conf_thres = 0.25
iou_thres = 0.45
input_width = 640
input_height = 480
model_name = 'yolov7-tiny'
model_path = "./model"
config_path = "./config"
result_path = "./result"
image_path = "./dataset/bus.jpg"
#video_path = "test.mp4"
video_path = 0
video_inference = True
RKNN_MODEL = f'{model_path}/{model_name}-{input_height}-{input_width}.rknn'
CLASSES = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train',
'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter',
'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear',
'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase',
'frisbee', 'skis','snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball
glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass',
'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich',
'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair',
'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop',
'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',
'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair
drier', 'toothbrush']
app = Flask(__name__)

def gen_frames(): # generate frame by frame from camera


camera = cv2.VideoCapture(0)

while True:
# Capture frame-by-frame
success, frame = camera.read() # read the camera frame
if not success:
print('camera_fail((')
break
else:
print('camera+')
ret, buffer = cv2.imencode('.jpg', frame)
frame = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') #
concat frame one by one and show result

def gen_frames_yolo():
cap = cv2.VideoCapture(video_path)
while(True):
ret, image_3c = cap.read()
if not ret:
break
print('--> Running model for video inference')
image_4c, image_3c = preprocess(image_3c, input_height, input_width)
outputs = rknn_lite.inference(inputs=[image_3c])
outputs[0] = np.squeeze(outputs[0])
outputs[0] = np.expand_dims(outputs[0], axis=0)
colorlist = gen_color(len(CLASSES))
results = postprocess(outputs, image_4c, image_3c, conf_thres,
iou_thres) ##[box,mask,shape]
results = results[0] ## batch=1
boxes, shape = results
if isinstance(boxes, np.ndarray):
vis_img = vis_result(image_3c, results, colorlist, CLASSES,
result_path)
#cv2.imshow("vis_img", vis_img)
ret, buffer = cv2.imencode('.jpg', vis_img)
vis_img = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + vis_img + b'\r\n')
else:
print("No detection result")
cv2.waitKey(1)

@app.route('/video_feed')
def video_feed():
#Video streaming route. Put this in the src attribute of an img tag
return Response(gen_frames_yolo(), mimetype='multipart/x-mixed-replace;
boundary=frame')

@app.route('/')
def index():
"""Video streaming home page."""
return render_template('index.html')

if __name__ == '__main__':

isExist = os.path.exists(result_path)
if not isExist:
os.makedirs(result_path)
rknn_lite = RKNNLite(verbose=False)
ret = rknn_lite.load_rknn(RKNN_MODEL)
ret = rknn_lite.init_runtime()

app.run(host='192.168.31.31', port=8080, debug=True)

Запустите приложение

python3 Live-Streaming-using-OpenCV-Flask/app.py

Откройте в браузере http://192.168.31.31:8080/


Если вы все сделали правильно в браузере вы получите подобную картину:

Заключение
В этом практическом занятии мы освоили развертывание моделей компьютерного
зрения на одноплатном компьютере.
Этот пайплайн вы можете повторять и для своих моделей в будущих проектах.

Вам также может понравиться