基于Jetson nano的餐厅自助结账系统部署

  • 一. 前言
  • 二. 开发环境
    • 2.1 硬件
    • 2.2 软件
  • 三. Jetson nano基础环境配置
    • 3.1 镜像烧录
    • 3.2 网络连接
    • 3.3 更换镜像源
    • 3.4 安装pip并换源
    • 3.5 远程登录
  • 四. 摄像头测试
  • 五. 安装PaddlePaddle开发环境
  • 六. 测试Paddle Inference
    • 6.1 跑通demo
    • 6.2 扩大运行内存
  • 七. 部署自己的目标检测模型
    • 7.1 导出推理模型
    • 7.2 准备预测部署程序
    • 7.3 添加GUI界面
    • 7.4 更改预测模式
  • 八. 效果展示
  • 九. 总结

一. 前言

本文是餐厅自助结账系统的硬件部署部分,关于目标检测部分请大家移步:【AI达人创造营第二期】餐厅自助结账系统之目标检测部分

本文全程参考了这三位大佬的文章,在此特表示感谢:

  • 【从踩坑到入门】基于Jetson Nano的深度学习模型部署教程

  • 在Jetson Nano上基于python部署Paddle Inference

  • 【飞桨领航团AI创造营+部署】EdgeBoard上实现电梯电瓶车检测

二. 开发环境

2.1 硬件

  • Jetson nano
  • 笔记本电脑
  • 支持HDMI的屏幕
  • 外接鼠标和键盘
  • 网线
  • CSI摄像头
  • 32G存储卡

2.2 软件

Jetson nano

  • Ubuntu 18.04
  • Jetson nano软核 4.6.1
  • Python 3.6.9
  • PaddlePaddle 2.2.3

笔记本电脑

  • Windows 10
  • Python 3.6.5

三. Jetson nano基础环境配置

3.1 镜像烧录

Jetson Nano初体验之写入官方Ubuntu镜像

这里需要注意两点:

1. 烧录的镜像一定要去官网下载最新版本,否则会出错
2. 第一次登录Jetson nano一定要连接显示屏进行基础配置

3.2 网络连接

我采用的是利用网线连接nano和PC,共享PC网络的方法来实现网络连接:

  • Jetson Nano——通过网线实现笔记本ssh远程连接
  • Jetson Nano通过笔记本实现网络连接

偶尔可能出现突然连不上的情况,此时需要将无线网卡的共享关闭,插拔网线连接,再重新打开共享功能即可。

关于其他联网方法,大家可以参考:

  • Jetson Nano主板的五种联网方法
  • jetson nano 命令行连接wifi
  • Jetson nano 开机自动连接 Wifi
  • jetson nano设置静态ip和发出热点

3.3 更换镜像源

官方镜像默认的是Ubuntu官方源,在国内使用该源下载程序速度较慢,所以需要更换。

ubuntu镜像源更换_Jetson Nano 修改源镜像

3.4 安装pip并换源

Jetson Nano——安装pip并换源

3.5 远程登录

jetson nano远程登录教程(PuTTYssh远程登录、远程桌面VNC、winSCP文件传输)

四. 摄像头测试

CSI摄像头的连接方式如图所示,将插槽往上提即可打开插槽插入排线。


在终端输入ls /dev/video*,如果出现/dev/video0则说明摄像头连接成功。用下面这段程序测试一下摄像头是否正常,如果是USB摄像头,摄像头初始化改为cap = cv2.VideoCapture(0)

import cv2
import numpy as npdef video_demo():print("init")capture = cv2.VideoCapture("nvarguscamerasrc \!video/x-raw(memory:NVMM), width=640, height=480, format=NV12, framerate=30/1\!nvvidconv flip-method=0 ! videoconvert ! video/x-raw, format=BGR ! appsink")#0为电脑内置摄像头while(True):ret, frame = capture.read()#摄像头读取,ret为是否成功打开摄像头,true,false。 frame为视频的每一帧图像frame = cv2.flip(frame, 1)#摄像头是和人对立的,将图像左右调换回来正常显示。print("OK")cv2.imshow("video", frame)c = cv2.waitKey(50)if c == 27:breakcapture.release()
video_demo()
cv2.destroyAllWindows()

五. 安装PaddlePaddle开发环境

首先查看Jetpack的版本:cat /etc/nv_tegra_release

然后根据Jetpack和Python的版本在官网上下载对应的PaddlePaddle,比如我的Jetpack版本为6.1,Python版本为3.6.9。


将.whl文件下载后通过远程文件传输软件winscp上传到Jetson nano中,进入.whl所在的文件夹并输入以下命令安装:pip3 install paddlepaddle_gpu-2.1.1-cp36-cp36m-linux_aarch64.whl,最后测试一下PaddlePaddle是否安装成功:

# 打开python3测试
import paddle
paddle.fluid.install_check.run_check()

六. 测试Paddle Inference

6.1 跑通demo

首先拉取官方最新版本的Paddle-Inference-demo并解压:

#拉取Paddle-Inference-Demo
!git clone https://github.com/PaddlePaddle/Paddle-Inference-Demo.git
#解压
!unzip -oq /home/aistudio/Paddle-Inference-Demo-master.zip

Paddle-Inference-Demo/python路径下面可以看到官方提供了很多测试文件。

以口罩检测为例,进入mask_detection文件夹,仔细阅读README.md文件,首先下载模型:

cd models
sh model_downloads.sh

然后修改cam_video.py如下所示,并运行程序:

# -*- coding: UTF-8 -*-import cv2
from mask_detect import MaskPred# The MaskPred class implements the function of face mask detection,
# including face detection and face mask classification
mp = MaskPred(True ,True, 0)
# Turn on the first camera, 0 means device ID
cap = cv2.VideoCapture("nvarguscamerasrc \!video/x-raw(memory:NVMM), width=640, height=480, format=NV12, framerate=30/1\!nvvidconv flip-method=0 ! videoconvert ! video/x-raw, format=BGR ! appsink")
#cv2.namedWindow('Mask Detect')while True:ret, frame = cap.read()frame = cv2.flip(frame, 1)print("OK")result = mp.run(frame)result_img = result['img']# h, w, _ = result_img.shape# result_img = cv2.resize(result_img, (int(w * 0.3), int(h * 0.3)))cv2.imshow("image", result_img)c = cv2.waitKey(10)if c == 27:breakcap.release()
cv2.destroyAllWindows()

⭐需要注意的是摄像头结束时一定要释放掉cap.release(),否则下一次将无法正常开启。

#运行程序
python3 cam_video.py

其他案例的运行方法详见各个文件夹内的README.md文件,或者可以直接运行run.sh文件,但是需要事先将所有run.sh文件底部的python改为python3

# 运行run.sh
chmod +x run.sh
./run.sh

6.2 扩大运行内存

如果在运行demo的过程中出现了卡死的情况,可以通过以下方法扩大运行内存,至少8G:

sudo fallocate -l 8G /var/swapfile8G
sudo chmod 600 /var/swapfile8G
sudo mkswap /var/swapfile8G
sudo swapon /var/swapfile8G
sudo bash -c 'echo "/var/swapfile8G swap swap defaults 0 0" >> /etc/fstab'

七. 部署自己的目标检测模型

7.1 导出推理模型

在【AI达人创造营第二期】餐厅自助结账系统之目标检测部分中我们已经训练得到了目标检测模型,在该项目中我才用的是ppyolov2_r50vd_dcn模型,由于该模型推理速度慢,而且不支持TRT加速,所以我换成了yolov3_mobilenet_v1训练了一个新模型,训练步骤完全相同,训练完成后模型保存在PaddleDetection/output路径下。

运行下面这行命令将模型导出,如果想导出其他模型修改.yml.pdparams的路径即可:

# 模型导出
!python -u PaddleDetection/tools/export_model.py -c PaddleDetection/configs/yolov3/yolov3_mobilenet_v1_ssld_270e_voc.yml --output_dir=./339 \-o weights=PaddleDetection/output/yolov3_mobilenet_v1_ssld_270e_voc/319.pdparams

导出后我们得到得到以下两个文件:

  • 存储模型结构的inference.pdmodel
  • 存储模型参数的inference.pdiparams


将这两个模型文件传入Jetson nano即可,我为大家准备好了模型,大家可以自行下载:链接。

7.2 准备预测部署程序

新建一个.txt文件,用来存放标签及其对应的价格:

以下代码请在Jetson Nano上运行。

1. 导入资源库

import cv2
import numpy as np
from paddle.inference import Config
from paddle.inference import PrecisionType
from paddle.inference import create_predictor
import yaml
import time
import threading

2. 图像预处理

def resize(img, target_size):"""resize to target size"""if not isinstance(img, np.ndarray):raise TypeError('image type is not numpy.')im_shape = img.shapeim_size_min = np.min(im_shape[0:2])im_size_max = np.max(im_shape[0:2])im_scale_x = float(target_size) / float(im_shape[1])im_scale_y = float(target_size) / float(im_shape[0])img = cv2.resize(img, None, None, fx=im_scale_x, fy=im_scale_y)return imgdef normalize(img, mean, std):img = img / 255.0mean = np.array(mean)[np.newaxis, np.newaxis, :]std = np.array(std)[np.newaxis, np.newaxis, :]img -= meanimg /= stdreturn imgdef preprocess(img, img_size):mean = [0.485, 0.456, 0.406]std = [0.229, 0.224, 0.225]img = resize(img, img_size)img = img[:, :, ::-1].astype('float32')  # bgr -> rgbimg = normalize(img, mean, std)img = img.transpose((2, 0, 1))  # hwc -> chwreturn img[np.newaxis, :]

3. 模型配置和预测

def predict_config(model_file, params_file):'''函数功能:初始化预测模型predictor函数输入:模型结构文件,模型参数文件函数输出:预测器predictor'''# 根据预测部署的实际情况,设置Configconfig = Config()# 读取模型文件config.set_prog_file(model_file)config.set_params_file(params_file)# Config默认是使用CPU预测,若要使用GPU预测,需要手动开启,设置运行的GPU卡号和分配的初始显存。config.enable_use_gpu(500, 0)# 可以设置开启IR优化、开启内存优化。config.switch_ir_optim()config.enable_memory_optim()config.enable_tensorrt_engine(workspace_size=1 << 30, precision_mode=PrecisionType.Half,max_batch_size=1, min_subgraph_size=5, use_static=False, use_calib_mode=False)predictor = create_predictor(config)return predictordef predict(predictor, img):'''函数功能:初始化预测模型predictor函数输入:模型结构文件,模型参数文件函数输出:预测器predictor'''input_names = predictor.get_input_names()for i, name in enumerate(input_names):input_tensor = predictor.get_input_handle(name)input_tensor.reshape(img[i].shape)input_tensor.copy_from_cpu(img[i].copy())# 执行Predictorpredictor.run()# 获取输出results = []# 获取输出output_names = predictor.get_output_names()for i, name in enumerate(output_names):output_tensor = predictor.get_output_handle(name)output_data = output_tensor.copy_to_cpu()results.append(output_data)return results

4. 后处理

def draw_bbox_image(frame, result, label, threshold=0.5):for res in result:cat_id, score, bbox = res[0], res[1], res[2:]if score < threshold:continuefor i in bbox:int(i)xmin, ymin, xmax, ymax = bboxcv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (255,0,255), 2)print('category id is {}, bbox is {}'.format(cat_id, bbox))try:label_id = label[int(cat_id)]# #cv2.putText(图像, 文字, (x, y), 字体, 大小, (b, g, r), 宽度)cv2.putText(frame, label_id, (int(xmin), int(ymin-2)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 2)cv2.putText(frame, str(round(score,2)), (int(xmin), int(ymin+8)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)except KeyError:passdef show_price(frame, result, label, price, threshold=0.5):w, h, _ = img.shapeprice_sum = 0 #记录总价label_sum = [] #记录购买的食物for res in result:cat_id, score, bbox = res[0], res[1], res[2:]if score < threshold:continuelabel_sum.append(label[int(cat_id)])price_sum += int(price[int(cat_id)])cv2.putText(frame, "price:"+str(price_sum), (int(w-4), 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)if len(label_sum) > 0:print("您挑选了%d份食物,总共%d元" % (len(label_sum),price_sum))else:print("请挑选食物")

5. 定义摄像头类

在实际运行过程中,如果摄像头帧率较高,但nano的处理速度跟不上时,会出现卡帧的情况,这时我们可以通过多线程的技巧改善这一问题。

class Camera:def __init__(self, src=0):self.src = srcself.stream = cv2.VideoCapture(src)self.stopped = Falseself.thread =  threading.Thread(target=self.update, args=())for _ in range(10): #warm up the camera(self.grabbed, self.frame) = self.stream.read()def start(self):self.thread.start()def update(self):while True:if self.stopped:return(self.grabbed, self.frame) = self.stream.read()def read(self):return self.grabbed, self.framedef stop(self):self.stopped = Truedef release(self):self.stream.release()

6. 主函数

# 从.txt文件中读取label
f = open("./label_list.txt")
label_list = f.read().splitlines()
label = [i.split(":")[0] for i in label_list]
price = [i.split(":")[1] for i in label_list]
print(label)
print(price)
f.close()# 配置模型参数
model_file = "./model/yolo/model.pdmodel"
params_file = "./model/yolo/model.pdiparams"
# 初始化预测模型
predictor = predict_config(model_file, params_file)cap = Camera("nvarguscamerasrc \!video/x-raw(memory:NVMM), width=640, height=480, format=NV12, framerate=30/1\!nvvidconv flip-method=0 ! videoconvert ! video/x-raw, format=BGR ! appsink")
cap.start()# 图像尺寸相关参数初始化
ret, img = cap.read()
if ret==False:while True:print("error")
im_size = 608
scale_factor = np.array([im_size * 1. / img.shape[0], im_size * 1. / img.shape[1]]).reshape((1, 2)).astype(np.float32)
im_shape = np.array([im_size, im_size]).reshape((1, 2)).astype(np.float32)while True:ret, frame = cap.read()# print(frame)# 预处理data = preprocess(frame, im_size)time_start = time.time()# 预测result = predict(predictor, [im_shape, data, scale_factor])# print(result)print('Time Cost:{}'.format(time.time()-time_start) , "s")draw_bbox_image(frame, result[0], label, threshold=0.5)show_price(frame, result[0], label, price, threshold=0.5)cv2.imshow("frame", frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakprint("break")
cap.stop()
cap.release()
cv2.destroyAllWindows()

运行后效果如图所示:

7.3 添加GUI界面

为了增强系统的操作性,我在前面目标检测的基础上增加了GUI界面。为了提高程序的可读性,我将代码分成了detect.pyGUI.py两个文件:

  • detect.py: 包括图像预处理、模型的配置和预测、图像后处理等与目标检测相关的函数。
  • GUI.py: 包括GUI界面显示相关函数和主函数。

1. detec.py

import cv2
import numpy as np
from paddle.inference import Config
from paddle.inference import PrecisionType
from paddle.inference import create_predictor
import yaml
import time
import threadingdef resize(img, target_size):"""resize to target size"""if not isinstance(img, np.ndarray):raise TypeError('image type is not numpy.')im_shape = img.shapeim_size_min = np.min(im_shape[0:2])im_size_max = np.max(im_shape[0:2])im_scale_x = float(target_size) / float(im_shape[1])im_scale_y = float(target_size) / float(im_shape[0])img = cv2.resize(img, None, None, fx=im_scale_x, fy=im_scale_y)return imgdef normalize(img, mean, std):img = img / 255.0mean = np.array(mean)[np.newaxis, np.newaxis, :]std = np.array(std)[np.newaxis, np.newaxis, :]img -= meanimg /= stdreturn imgdef preprocess(img, img_size):mean = [0.485, 0.456, 0.406]std = [0.229, 0.224, 0.225]img = resize(img, img_size)img = img[:, :, ::-1].astype('float32')  # bgr -> rgbimg = normalize(img, mean, std)img = img.transpose((2, 0, 1))  # hwc -> chwreturn img[np.newaxis, :]def predict_config(model_file, params_file):'''函数功能:初始化预测模型predictor函数输入:模型结构文件,模型参数文件函数输出:预测器predictor'''# 根据预测部署的实际情况,设置Configconfig = Config()# 读取模型文件config.set_prog_file(model_file)config.set_params_file(params_file)# Config默认是使用CPU预测,若要使用GPU预测,需要手动开启,设置运行的GPU卡号和分配的初始显存。config.enable_use_gpu(500, 0)# 可以设置开启IR优化、开启内存优化。config.switch_ir_optim()config.enable_memory_optim()#config.enable_tensorrt_engine(workspace_size=1 << 30, precision_mode=PrecisionType.Half,max_batch_size=1, min_subgraph_size=5, use_static=False, use_calib_mode=False)predictor = create_predictor(config)return predictordef predict(predictor, img):'''函数功能:初始化预测模型predictor函数输入:模型结构文件,模型参数文件函数输出:预测器predictor'''input_names = predictor.get_input_names()for i, name in enumerate(input_names):input_tensor = predictor.get_input_handle(name)input_tensor.reshape(img[i].shape)input_tensor.copy_from_cpu(img[i].copy())# 执行Predictorpredictor.run()# 获取输出results = []# 获取输出output_names = predictor.get_output_names()for i, name in enumerate(output_names):output_tensor = predictor.get_output_handle(name)output_data = output_tensor.copy_to_cpu()results.append(output_data)return resultsdef draw_bbox_image(frame, result, label, threshold=0.5):for res in result:cat_id, score, bbox = res[0], res[1], res[2:]if score < threshold:continuefor i in bbox:int(i)xmin, ymin, xmax, ymax = bboxcv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (255,0,255), 2)#print('category id is {}, bbox is {}'.format(cat_id, bbox))try:label_id = label[int(cat_id)]# #cv2.putText(图像, 文字, (x, y), 字体, 大小, (b, g, r), 宽度)cv2.putText(frame, label_id, (int(xmin), int(ymin-2)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 2)cv2.putText(frame, str(round(score,2)), (int(xmin), int(ymin+8)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)except KeyError:passdef show_price(frame, result, label, price, threshold=0.5):w, h, _ = frame.shapeprice_sum = 0 #记录总价label_sum = [] #记录购买的食物for res in result:cat_id, score, bbox = res[0], res[1], res[2:]if score < threshold:continuelabel_sum.append(label[int(cat_id)])price_sum += int(price[int(cat_id)])cv2.putText(frame, "price:"+str(price_sum), (int(w-4), 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)if len(label_sum) > 0:print("您挑选了%d份食物,总共%d元" % (len(label_sum),price_sum))else:print("请挑选食物")return label_sum,price_sumclass Camera:def __init__(self, src=0):self.src = srcself.stream = cv2.VideoCapture(src)self.stopped = Falseself.thread =  threading.Thread(target=self.update, args=())for _ in range(10): #warm up the camera(self.grabbed, self.frame) = self.stream.read()def start(self):self.thread.start()def update(self):while True:if self.stopped:return(self.grabbed, self.frame) = self.stream.read()def read(self):return self.grabbed, self.framedef stop(self):self.stopped = Truedef release(self):self.stream.release()def isOpened(self):return self.stream.isOpened()

2. GUI.py

当摄像头采用多线程时系统运行过程中会出现意外的现象,因此这里摄像头不采用多线程。

from glob import glob
import cv2
import tkinter
from tkinter import messagebox
import numpy as np
from PIL import Image,ImageTk
import matplotlib.pyplot as plt
import time
from detect import *'''预测模型准备工作开始'''
# 从.txt文件中读取label
f = open("./label_list.txt")
label_list = f.read().splitlines()
label = [i.split(":")[0] for i in label_list]
price = [i.split(":")[1] for i in label_list]
print(label)
print(price)
f.close()# 配置模型参数
model_file = "./model/yolo/model.pdmodel"
params_file = "./model/yolo/model.pdiparams"
# 初始化预测模型
predictor = predict_config(model_file, params_file)cap = cv2.VideoCapture("nvarguscamerasrc !video/x-raw(memory:NVMM), width=640, height=480, format=NV12, framerate=30/1 !nvvidconv flip-method=0 ! videoconvert ! video/x-raw, format=BGR ! appsink")
# cap = Camera("nvarguscamerasrc \
#                     !video/x-raw(memory:NVMM), width=640, height=480, format=NV12, framerate=30/1\
#                     !nvvidconv flip-method=0 ! videoconvert ! video/x-raw, format=BGR ! appsink")
# cap.start()# 图像尺寸相关参数初始化
ret, img = cap.read()
if ret==False:while True:print("error")
im_size = 608 #开启TensorRT加速后改为608,否则为640
scale_factor = np.array([im_size * 1. / img.shape[0], im_size * 1. / img.shape[1]]).reshape((1, 2)).astype(np.float32)
im_shape = np.array([im_size, im_size]).reshape((1, 2)).astype(np.float32)
# cap.stop()
cap.release()
'''预测模型准备工作结束''''''tkinter准备'''
win = tkinter.Tk()
win.title("餐厅自助结账系统")
win.geometry("600x570")image_path = '1.jpg' #系统初始封面地址
root = win
cap = None#设置显示的图像大小
img_width = 550
img_height=400
#图像处理
def TKImages(frame):#摄像头翻转#frame = cv2.flip(frame,1)image =cv2.cvtColor(frame,cv2.COLOR_BGR2RGBA)image = image.astype(np.uint8)PILimage = Image.fromarray(image)PILimage = PILimage.resize((img_width,img_height),Image.ANTIALIAS)try:tkImage = ImageTk.PhotoImage(image=PILimage)except:return 0return tkImagedef Canvas():# 创建画布canvas = tkinter.Canvas(root, bg='white', width=img_width, height=img_height)canvas.place(x=25, y=35)# 创建标签label1 = tkinter.Label(root, text='餐厅自助结账系统', font=('黑体', 14), width=15, height=1)# `anchor=nw`则是把图片的左上角作为锚定点label1.place(x=223, y=0, anchor='nw')label2 = tkinter.Label(root, text='制作人:陈悦江', font=('黑体', 14), width=15, height=1)# `anchor=nw`则是把图片的左上角作为锚定点label2.place(x=430, y=510, anchor='nw')return canvas#关闭系统
def Destroy_all():global capif cap != None and cap.isOpened():#cap.stop()cap.release()cv2.destroyAllWindows()root.destroy()#这里需要将tkImage设置为全局变量,不然显示不出图片
tkImage=''
def set_BackGround():global tkImagecanvas = Canvas()img = cv2.imread(image_path)tkImage = TKImages(img)canvas.create_image(0, 0, anchor='nw', image=tkImage)#停止检测函数
def Close_Video():global cap#cap.stop()cap.release()cv2.destroyAllWindows()Init()#初始化整个界面
def Init():set_BackGround()btn_2 = tkinter.Button(root, text='开始检测', font=('黑体', 14), height=1, width=15,command=lambda: Detect_Real_Time())btn_2.place(x=220, y=435)btn_close=tkinter.Button(root,text='退出检测',font=('黑体', 14),  width=15,height=1,command=lambda: Destroy_all())btn_close.place(x=220,y=480)def Detect_Real_Time():print("开始检测")global capcap = cv2.VideoCapture("nvarguscamerasrc !video/x-raw(memory:NVMM), width=640, height=480, format=NV12, framerate=30/1 !nvvidconv flip-method=0 ! videoconvert ! video/x-raw, format=BGR ! appsink")# cap = Camera("nvarguscamerasrc \#                     !video/x-raw(memory:NVMM), width=640, height=480, format=NV12, framerate=30/1\#                     !nvvidconv flip-method=0 ! videoconvert ! video/x-raw, format=BGR ! appsink")#cap.start()#停止检测按钮btn = tkinter.Button(root, text='停止检测', font=('黑体',14),width=15,height=1,command=lambda :Close_Video())btn.place(x=220, y=435)#退出检测按钮btn_close=tkinter.Button(root,text='退出检测',font=('黑体', 14),  width=15,height=1,command=lambda: Destroy_all())btn_close.place(x=220,y=480)canvas = Canvas()i=0 #标志位while True:print("正在检测")'''目标检测'''OK,frame=cap.read()if OK==False:print('检测失败')break# 预处理data = preprocess(frame, im_size)#time_start = time.time()# 预测result = predict(predictor, [im_shape, data, scale_factor])#print('Time Cost:{}'.format(time.time()-time_start) , "s")# 绘制边框draw_bbox_image(frame, result[0], label, threshold=0.7)#显示价格label_sum, price_sum = show_price(frame, result[0], label, price, threshold=0.7)if len(label_sum) > 0: #判断识别到的种类是否大于0if i == 0: #第一次识别到label_sum_last = label_sumi += 1else:if label_sum_last == label_sum: # 如果这次识别的跟上一次的一样i += 1else:i = 0label_sum_last = label_sumelse:i = 0'''tkinter'''pic=TKImages(frame)canvas.create_image(0,0,anchor='nw',image=pic)#连续10帧识别到一样的食物if i==10:buy = tkinter.messagebox.askquestion(title="请确认支付", message="您挑选了%d份食物,总共%d元" % (len(label_sum),price_sum))if buy=='yes':qrcode = Image.open("2.jpg") #二维码地址qrcode = qrcode.resize((292,400),Image.ANTIALIAS)qrcode.show()while True:c = input("请确认支付:") if c=='qr' or c=='qx':breakelse:print("支付失败")continueif c=='qr':print("已支付")else:print("已取消")else:print("已取消")i=0root.update()root.after(1)#cap.stop()cap.release()cv2.destroyAllWindows()Init()
win.mainloop()

运行GUI.py后得到运行效果如图所示:

7.4 更改预测模式

所有的模式都在predict_config()函数中,其中:

  • GPU预测config.enable_use_gpu(500, 0)(注释掉该代码即为CPU模式)
  • 开启IR优化、开启内存优化config.switch_ir_optim()config.enable_memory_optim() (一般都开启)
  • TensorRT加速config.enable_tensorrt_engine()

关于TRT的资料可以参考:https://paddle-inference.readthedocs.io/en/master/optimize/paddle_trt.html ,其中静态shape支持以下模型:


我给大家提供的两个模型分别是ppyoloyolo3,其中ppyolo不支持TRT加速,GPU预测每帧大约为0.85s左右;yolo3采用GPU预测每帧大约为0.29s左右,TRT加速后每帧大约为0.16s左右。

八. 效果展示

【AI达人训练营第二期】基于Jetson nano的餐厅自助结账系统部署

九. 总结

  • 整个部署流程断断续续花了一周的时间完成,在这一周的时间里自己对于目标检测及Linux操作等技术都有了明显地提升,在此非常感谢百度飞桨能提供这次宝贵的机会,同时也非常感谢群里为我解答问题的小伙伴和各位百度飞桨的开源工作者。
  • 当前只是完成了一个最基本的部署部分,要想实现项目的落地还有很多功能需要完善,比如提高模型检测精度,与语音播报系统、二维码扫描支付等系统相结合等。

【AI达人创造营第二期】基于Jetson nano的餐厅自助结账系统部署相关推荐

  1. 【AI达人创造营第二期】基于PaddleClas的新冠肺炎CT影像的分类

    转自AI Studio,原文链接:[AI达人创造营第二期]基于PaddleClas的新冠肺炎CT影像的分类 - 飞桨AI Studio 一.项目背景 新近爆发的2019新型冠状病毒(SARS-CoV- ...

  2. 【AI达人创造营第二期】基于PaddlePaddle的影像复原及修复实现

    基于PaddlePaddle2.2的影像复原及修复实现 标题转载自AI Studio 标题项目链接https://aistudio.baidu.com/aistudio/projectdetail/3 ...

  3. 【组队学习】【34期】百度飞桨AI达人创造营

    百度飞桨AI达人创造营 航路开辟者:百度飞桨 领航员:六一 航海士:阿水.颜鑫.宋泽山.刘洋.张文恺 基本信息 内容属性:合作课程 练习平台:https://aistudio.baidu.com/ai ...

  4. 【AI达人创造营三期】在地平线X3上部署车牌识别系统

    [AI达人创造营三期]在地平线X3上部署车牌识别系统 一. 项目介绍 本项目属于AI达人创造营三期项目,主要探索如何将PaddleOCR训练的车牌识别模型部署在地平线X3的板子上,并实现实时推理. 二 ...

  5. 百度AI达人创造营|第一课、拍案叫绝的创意

    百度AI达人创造营 课程设计 课程 内容 第一课 让人拍案叫绝的创意都是如何诞生的 第二课 数据集的获取途径和数据处理的技巧 第三课 深度学习模型训练和关键参数调优详解 第四课 教你5种简单高效的部署 ...

  6. 【AI达人创造营】红细胞形状异常检测在Edgeboard上的部署

    [AI达人创造营]红细胞形状异常检测在Edgeboard上的部署 此项目是基于PaddleDetection做的红细胞形状异常检测,属于医学中目标检测类的项目.此项目是在由百度大脑研发的EdgeBoa ...

  7. 飞浆领航团AI达人创造营第01课|让人拍案叫绝的创意都是如何诞生的?

     时间:2021年7月27日 下午18:25 内容:创意的获取渠道和创意的评估方法 昨晚看了飞桨领航团AI达人创造营的第一节直播,现在将第一节的笔记以及感受整理如下,依次来激励自己的后续学习,希望能过 ...

  8. 【AI达人创造营三期-Antigen Detector(新冠试剂盒检测)部署】

    (前言)Jetson TX2推理效果展示: 配套原项目地址Antigen Detector(新冠试剂盒检测) 1 推理时间 YOLOE+Faiss-cpu检索Infer Time在400ms-700m ...

  9. 笔记 | 百度飞浆AI达人创造营:深度学习模型训练和关键参数调优详解

    笔记 | 百度飞浆AI达人创造营:深度学习模型训练和关键参数调优详解 针对特定场景任务从模型选择.模型训练.超参优化.效果展示这四个方面进行模型开发. 一.模型选择 从任务类型出发,选择最合适的模型. ...

最新文章

  1. fp格式图片_2020Pamp;I | 适马无反版100-400镜头亮相,fp全幅微单满足不同需求
  2. datagrid中巧用loadFilter对数据整形
  3. OpenCV下设置灰度直方图的阈值来对图像进行查找(查表)变换的源码
  4. 发生在“注解”@的那些事儿
  5. webpack入门+react环境配置 1
  6. 谷歌官方推出 TensorFlow 中文视频:机器学习从零到一(系列之二)
  7. JVM Java内存区域 与 内存溢出 (系列号1)
  8. Docker 安装 maven 私服
  9. Cuda Graph (cuda 优化)
  10. 产品配件类目税目分类_商品类别税率一览表
  11. 坚果云+Typora+vscode 参考notion 进行个人知识管理
  12. 既然阻塞 I/O 会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?
  13. 数字化转型具体包含哪些内容?
  14. Tableau:1、简单总结
  15. 如何用 Python 爬取网易云音乐歌单
  16. Sqoop常用命令回顾
  17. 千兆以太网测试仪什么牌子好
  18. OPPOa5m手机Android,OPPO A5怎么样?OPPO A5手机体验评测
  19. OpenCV 各版本百度云下载
  20. svchost.exe(LocalSystemNetworkRestricted)占用内存以及CPU

热门文章

  1. 球球大作战如何在电脑上玩 球球大作战电脑版教程
  2. mysql 1035_db2删除数据库SQL1035N 数据库当前正在使用。 SQLSTATE=57019
  3. 如何搭建一个盈利网站
  4. 项目管理-计算专题(三点估算、PERT估算)
  5. 微信H5页面禁用复制链接
  6. 三星手机CROM锁、OEM锁等概念的区别
  7. 单片机应用系统设计技术——计数器
  8. python从excel中读取数据并填写网页表格
  9. 阿德莱德大学计算机专业学费,2020年阿德莱德大学计算机科学专业研究生申请条件及世界排名|学费介绍...
  10. html中table代表什么,html中的table详解