1. 简介

1.1 背景与意义简介

  • 目标跟踪是计算机视觉领域的一个重要问题,目前广泛应用在体育赛事转播、安防监控和无人机、无人车、机器人等领域。在篮球比赛的场景中,主要是针对篮球和运动员的检测。通过对这些目标的检测,进一步实现摄像头对比赛主体的位置跟踪或是放大。
  • JetsonNano是NVIDIA推出的高性能边缘端部署小型计算设备

  • 可以在JetsonNano上实现录制球场比赛视频,实时或延时进行推理处理,完成目标检测与分割。
  • 为之后体育赛事的转播,录播处理提供新思路。

1.2 效果预览

  • 本项目基于PaddleSeg和PaddleDetection的视频篮球和运动员检测分割中已经训练好的模型,在Jetson Nano上部署
  • 部署思路:
  • 思路一:通过CSI摄像头实时读取图像,对实时画面中的篮球或运动员进行检测,并框出运动员和篮球的位置,并保存视频文件,主要使用PaddleInference来进行推理。
  • 思路二:因为JetsonNano端的性能可能不太适合实时的模型推理,会有视频卡帧的现象。因此考虑通过CSI摄像头实现录制功能,对一段时间的画面进行录制,之后在Jetson Nano端使用模型进行推理,最后输出视频文件
  • 效果预览
    https://www.bilibili.com/video/BV1N24y1o7Xg/?vd_source=f1859d340cedaa4a4e046fd30be2cb9b

2. 开发环境搭建

2.1 硬件

  • 收到Jetson Nano B01套件后进行简单的组装

    组装完成效果如下

  • 之后获取NVIDIA官方的IMG准备进行烧写
  • 可以使用balenaEtcher进行烧写
  • 将烧入官方IMG的microSD卡直接插入JetsonNano的SD卡插槽即可

    如下图

  • 上电开机,接入屏幕。
  • 为了让风扇运转可以使用
$ sudo sh -c 'echo 200 > /sys/devices/pwm-fan/target_pwm'

进行调节,其中200的位置可以是0~255任意整数,越大风扇转速越高

  • 除此之外也可以安装jtop进行系统资源的监控,这里也可以调节风扇
$ sudo apt-get update
$ sudo apt-get install python3-pip
$ pip3 install --upgrade pip
$ sudo -H pip3 install jetson-stats
$ sudo jtop

界面如下:

在CTRL选项卡内可以直接调节分风扇转速,也可以设置为自动模式,根据温度自动调节

在MEM选项卡可以设置 swapfile大小设置交换内存

2.2 网络设置

  • 为了开发方便,可以在Windows主机上简单搭建NFS服务器,共享文件夹给Jetson Nano。

  • 用网线连接Windows主机和JetsonNano

  • 配置Windows主机的IP:

    设置->网络和Internet->高级网络设置->选择与JetsonNano所连接的网络适配器->查看其它属性->编辑IPv4地址

    例如192.168.1.2/24,如下图

  • 配置JetsonNano端IP

$ sudo vi /etc/network/interfaces

在该文件中加入

auto eth0
iface eth0 inet static
address 192.168.1.165
netmask 255.255.255.0
  • 之后从重新启用eth0
$ sudo service network-manager restart
$ sudo ifdown eth0
$ sudo ifup eth0
  • 通过$ ifconfg eth0查看是否配置好

其中ip address设置与Windows端在同一子网下,配置好后通过互相ping检查是否连通。

  • 使用haneWIN NFS Server,配置过程参考这篇博客
  • 在Windows主机上搭建好NFS Server后,在Jetson Nano端输入mount命令将共享的文件夹挂载到本地的目录下
$ sudo mount -t nfs -o nolock 192.168.1.2:/e/JetsonNano/Shared ~/WinShared/

其中192.168.1.2为Windows主机配置的IP,/e/JetsonNano/Shared为Windows主机中被共享出去的文件夹,~/WinShared/为JetsonNano中挂载共享文件夹的目录

  • 挂载上后即可通过~/WinShared访问目录,在Windows上使用PyCharm编写项目的主要代码,在JetsonNano上运行即可

2.3 库的安装

  • 首先使用$ jtop的INFO选项卡查看主要的SDK信息,如下图所示

  • JetPack版本为4.6.1
$ pip3 install numpy==1.16.1
$ python3 --version
  • Python的预装版本为3.6.9
  • 在PaddleInference官网下载nano,JetPack 4.6.1,python3.6对应的paddlepaddle即可
  • 可以放在共享文件夹下
$ pip3 install paddlepaddle_gpu-2.3.0-cp36-cp36m-linux_aarch64.whl

安装paddlepaddle

3. 界面实现

  • 最后使用PyQt实现简单的各类检测集成的界面。由于官方镜像中PyQt5使用的gtk不适配,使用cv2.imshow就会报错,需要输入以下命令
$ sudo apt-get build-dep qt5-default
$ sudo apt install libcanberra-gtk-module
$ sudo apt install qt5-style-plugins
$ echo "export QT_QPA_PLATFORMTHEME=gtk2" >> ~/.profile

具体可参考此链接

  • 使用Qt Designer实现界面的设计,如下图:

  • 界面见start_test.py

  • 主要实现的功能有测试摄像头,录制视频,读取视频,篮球运动员实时检测,篮球实时检测,篮球和运动员的视频处理,篮球运动员分割视频处理,见start.py

4. 实时篮球检测

  • 首先将训练过的basketball_detection_model推理模型下载,放在工作目录的PaddleDetection/output_inference/
  • 使用PaddleDetection中的python推理infer.py
    因为camera_id只能传参整数,而在JestsonNano上使用CSI摄像头需要特殊的参数

将源码中capture=cv2.VideoCapture(camera_id)修改为

capture = cv2.VideoCapture("nvarguscamerasrc sensor-id=0 !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")
  • 之后通过,os.system调用infer.py即可,主要实现代码如下(截取start.py部分)
    def bsk_dtc(self):if not self.check_store_path(): returntarget_dir = self.video_record_le.text() + os.sepcommand = r'python3 PaddleDetection/deploy/python/infer.py \--model_dir=PaddleDetection/output_inference/basketball_detection_model \--camera_id=0 \--threshold=0.8 \--device=GPU \--output_dir=' + target_diros.system(command)return
  • 检测输入的视频存储路径和视频读取路径是否合法check_store_parth()check_read_path()
# 检查读取的视频位置是否存在def check_read_path(self) -> bool:src_path = self.read_video_le.text()if not os.path.isfile(src_path):msg_box = QMessageBox(QMessageBox.Information, '错误', '视频文件不存在')msg_box.exec_()return False# 判断是否为视频文件name = src_path.split(os.sep)[-1]if name.endswith(('.mp4', '.avi', '.mkv', '.wmv', '.iso')):return Trueelse:return False# 检查存储视频的目录是否合法def check_store_path(self) -> bool:text = self.video_record_le.text()if text.__len__() == 0:msg_box = QMessageBox(QMessageBox.Information, '错误', '视频存储路径不能为空')msg_box.exec_()return Falsetarget_dir = self.video_record_le.text() + os.sepif not os.path.isdir(target_dir):msg_box = QMessageBox(QMessageBox.Information, '错误', '目录不存在')msg_box.exec_()return Falsereturn True

5. 实时运动员检测

  • 下载PPhuman的mot_ppyoloe_l_36e_pipeline推理模型,放在工作目录的PaddleDetection/output_inference/
  • 使用PaddleDetection中的python推理脚本infer.py
  • 之后通过,os.system调用infer.py即可,主要实现代码如下(截取start.py部分)
    def player_dtc(self):if not self.check_store_path(): returntarget_dir = self.video_record_le.text() + os.sepcommand = r'python3 PaddleDetection/deploy/python/infer.py \--model_dir=PaddleDetection/output_inference/mot_ppyoloe_l_36e_pipeline \--camera_id=0 \--threshold=0.8 \--device=GPU \--output_dir=' + target_diros.system(command)return

6. 篮球运动员检测视频处理

  • 视频处理同样使用infer.py,不使用camera_id,使用video_file参数指定视频位置
  • 主要代码如下,先处理运动员检测,再处理篮球检测
    def bsk_ply_dtc(self):if not self.check_store_path(): returntarget_dir = self.video_record_le.text() + os.septmp_dir = os.path.join(target_dir, 'tmp')if not os.path.isdir(tmp_dir):os.mkdir(tmp_dir)if not self.check_read_path(): returnsrc_path = self.read_video_le.text()name = src_path.split(os.sep)[-1]if not name.endswith('.mp4'):name = 'output.mp4'command = r'python3 PaddleDetection/deploy/python/infer.py \--model_dir=PaddleDetection/output_inference/mot_ppyoloe_l_36e_pipeline \--video_file=' + src_path + r' \--threshold=0.8 \--device=GPU \--output_dir=' + tmp_diros.system(command)middle_path = os.path.join(tmp_dir, name)command = r'python3 PaddleDetection/deploy/python/infer.py \--model_dir=PaddleDetection/output_inference/basketball_detection_model \--video_file=' + middle_path + r' \--threshold=0.5 \--device=GPU \--output_dir=' + target_diros.system(command)

如下图所示效果

7. 实现篮球和运动员分割

  • 使用训练好的basketball_player_seg_640x640模型
  • 使用PaddleSeg中的infer.py
    def seg_video(self):if not self.check_store_path(): returntarget_path = self.video_record_le.text() + os.sepif not self.check_read_path(): returnsrc_path = self.read_video_le.text()name = src_path.split(os.sep)[-1]name=name.split('.')[0]#临时存放视频帧的文件夹tmp_path=os.path.join(target_path,'tmp_seg_img/')if not os.path.isdir(tmp_path):os.mkdir(tmp_path)tmp_in=os.path.join(tmp_path,'tmp_in/')if not os.path.isdir(tmp_in):os.mkdir(tmp_in)tmp_out=os.path.join(tmp_path,'tmp_out/')if not os.path.isdir(tmp_out):os.mkdir(tmp_out)#读取视频文件cap=cv2.VideoCapture(src_path)fps = cap.get(cv2.CAP_PROP_FPS)  # 获取视频的帧率width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 获取视频的帧宽度height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 获取视频的帧高度fcount = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))  # 获取视频中的帧数目for index in tqdm(range(fcount)):ret, frame = cap.read()  # 读取视频中的一帧if not ret:breakcv2.imwrite(tmp_in + str(index) + '.png', frame)  # 保存该帧为png格式图片cap.release()os.system(r'python3 PaddleSeg/deploy/python/infer.py \--config PaddleSeg/inference_model/basketball_player_seg_640x640/deploy.yaml \--image_path '+tmp_in+r' \--save_dir '+tmp_out)#保存为MP4格式的视频out = cv2.VideoWriter(os.path.join(target_path,name+'.mp4'), cv2.VideoWriter_fourcc(*'mp4v'), fps,(width, height))for index in tqdm(range(fcount)):img_mark = cv2.imread(tmp_out + str(index) + '.png')img_src=cv2.imread(tmp_in + str(index) + '.png')#1:1混合显示img_dst=cv2.addWeighted(img_src,0.5,img_mark,0.5,0)out.write(img_dst)out.release()#删除暂时存放图片的文件夹os.system('rm -rf '+tmp_path)msg_box = QMessageBox(QMessageBox.Information, '处理完成', '视频存储为'+os.path.join(target_path,name+'.mp4'))msg_box.exec_()return

效果如下图

8. 其它功能

  • 测试摄像头,录制视频,读取视频功能
  • 主要代码如下:
    def read_video(self):if not self.check_read_path(): returnsrc_path = self.read_video_le.text()name = src_path.split(os.sep)[-1]cap = cv2.VideoCapture(src_path)fps = cap.get(cv2.CAP_PROP_FPS)wait_time = (1 / fps) * 0.8while cap.isOpened():# 画面暂留一段时间time.sleep(wait_time)ret, frame = cap.read()if ret:cv2.imshow(name, frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakelse:breakcap.release()cv2.destroyWindow(name)def video_record(self):if not self.check_store_path(): returntarget_dir = self.video_record_le.text() + os.sepprint('write video to ', target_dir)name = 'outcome.avi'target_path = target_dir + namecap = cv2.VideoCapture(camera_id)try:fps = cap.get(cv2.CAP_PROP_FPS)  # 获取视频的帧率width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 获取视频的帧宽度height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 获取视频的帧高度out = cv2.VideoWriter(target_path, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), fps,(width, height))  # 保存本地视频while True:ret, frame = cap.read()# 按Q退出out.write(frame.astype(np.uint8))cv2.putText(frame, 'press Q to end record', (5, 50,), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)cv2.imshow('record video', frame)if cv2.waitKey(1) & 0xFF == ord('q'):cap.release()out.release()msg_box = QMessageBox(QMessageBox.Information, '提示', '视频保存为' + target_path)msg_box.exec_()cv2.destroyWindow('record video')breakexcept Exception as e:print("video record failed:", e)cap.release()msg_box = QMessageBox(QMessageBox.Information, '错误', '视频录制失败')msg_box.exec_()returndef camera_test(self):cap = cv2.VideoCapture(camera_id)try:ret, frame = cap.read()# 等待摄像头启动while ret is False:ret, frame = cap.read()while True:ret, frame = cap.read()# 按Q退出cv2.putText(frame, 'press Q to exit', (5, 50,), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)cv2.imshow('test camera', frame)if cv2.waitKey(1) & 0xFF == ord('q'):cap.release()cv2.destroyWindow('test camera')breakexcept Exception as e:cap.release()print("camera campture failed:", e)msg_box = QMessageBox(QMessageBox.Information, '错误', '打开摄像头失败')msg_box.exec_()return

10. 总结

  • 在JetsonNano上部署需要搭建好开发环境,可以使用共享文件夹的方式来编写项目。
  • 在遇到JetsonNano相关的环境问题时可以上NVIDIA的官方论坛查找
  • JetsonNano的性能有限,主要是内存不太够,不太适合实时的使用训练的ppyoloe和ocrnet模型推理检测和分割。可以采用录制视频后再处理的方式。
  • 可以采用边缘端录制视频,传输给服务端运行模型检测和分割。
  • 可以进一步使用PaddleSlim优化模型,说不定可以加快模型的推理速度。
  • 语义分割的模型训练的数据集较小,因此没有很好的分割效果。
  • 篮球检测场景还可以加入对篮网,篮板等场景元素的检测。
  • 通过此次的项目,学到了如何在Jetson部署Paddle训练的模型,学到了如何使用PyQt完成简单的界面编写,体验了JetsonNano的推理速度。

此文章为搬运
原项目链接

【AI达人创造营三期】Jetson Nano篮球和运动员检测分割的部署相关推荐

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

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

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

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

  3. 【AI达人创造营三期】Jetson Nano实时监测学生坐姿,预防近视

    1.前言 本来以为jetson nano就是一台小型计算机而已,把模型复制到上面运行就可以了,可实际操作起来遇到了很多问题,踩了很多坑,现在整理一下. 参考资料: 基于FastDeploy将PicoD ...

  4. 【AI达人创造营三期】Fastdeploy与英特尔NUC推动智慧城市巡检应用落地

    Fastdeploy与英特尔NUC推动智慧城市巡检应用落地 1.项目背景 智慧城市是指利用大数据.物联网(IoT)人工智能和5G等数字技术,提高政府公共服务水平.社会治理效能.推动经济增长和不断增强人 ...

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

    基于Jetson nano的餐厅自助结账系统部署 一. 前言 二. 开发环境 2.1 硬件 2.2 软件 三. Jetson nano基础环境配置 3.1 镜像烧录 3.2 网络连接 3.3 更换镜像 ...

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

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

  7. 百度AI达人创造营之创意的起源

    百度AI达人创造营之"创意的起源" 文章目录 百度AI达人创造营之"创意的起源" 前言 一.关于飞桨及本次课程 二.创意从哪来呢? 1. 娱乐是生活的一部分(P ...

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

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

  9. 飞桨领航团AI达人创造营第一课2021.7.26

    系列文章目录 第一章.让人拍案叫绝的创意都是如何诞生的 文章目录 系列文章目录 前言 一.课程表 二.课程内容 总结 前言 暑期充电季,百度飞桨领航团全新推出"AI达人创造营",十 ...

最新文章

  1. SpringMVC中,前台jsp封装参数,绑定参数,传递参数到后台controller的过程详解
  2. python使用方法视频-python读取视频流提取视频帧的两种方法
  3. 再部署一个 instance 和 Local Network - 每天5分钟玩转 OpenStack(131)
  4. 【Mysql 学习路线图】
  5. FATFS里的FILINFO结构体详解
  6. 转:Python Shell 清屏方法
  7. 用C#编写的代码经C#编译器后,并非生成本地代码而是生成托管代码
  8. 程序员面试金典 - 面试题 16.26. 计算器(栈)
  9. linux重启用reboot后起不来_linux使用reboot重启后怎么办?
  10. Linux网络协议栈【转载】
  11. 创建C51工程文件疑问点---startup.A51
  12. Java太阳系行星运动模型
  13. itx机箱尺寸_讲解 ATX M-ATX ITX 各种主板尺寸
  14. 混沌数学之Lorenz(洛伦茨)吸引子
  15. GAPS-银行综合前置系统
  16. 征途LINUX服务端脚本,征途【改版教程】-版本内脚本文件-转载于-喜欢玩网游单机站...
  17. 一元多项式因式分解的唯一性定理
  18. IE浏览器浏览网页提示证书错误,Chrome、360浏览器显示“不安全”的原因
  19. Python查找特定名称文件
  20. 2026年预标准5G营收将达到2000亿美元

热门文章

  1. 图卷积网络GCN简介
  2. 微型计算机可以显示不同的,微型计算机可以配置不同的显示系统,如CCA、EGA和VGA,它们反映了显示设备的(...
  3. 周易六十四卦——大壮卦
  4. Zabbix 监控 CPU 使用率
  5. 015-Storm计算网站UV(去重计算模式)
  6. Compose系列:Recomposition重组作用域
  7. 笔记本电脑无法进入u盘启动界面怎么办?
  8. 配置ntp时钟同步(tar包方式安装ntp)
  9. 透明细胞肾细胞癌的发生及致死性机制(2021)
  10. 在KV260上玩转Kria Robotics Stack(KRS)