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

您所在的位置:网站首页 篮球运动员测试标准表 【AI达人创造营三期】Jetson Nano篮球和运动员检测分割的部署

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

2023-08-16 11:39| 来源: 网络整理| 查看: 265

简介 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,如下图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1zt6Etjg-1665146155622)(https://ai-studio-static-online.cdn.bcebos.com/8962658af78b4cfca2786559bc3e34fcdf0b20e034644352bf82765bef1a6a47)]

配置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查看是否配置好 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5NfZPuNA-1665146155624)(https://ai-studio-static-online.cdn.bcebos.com/4fcd045bbca5465893935005520350e8f3bcea4e6a0e4cfc89c39bdd8772953f)]

其中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(): return target_dir = self.video_record_le.text() + os.sep command = 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_dir os.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 True else: 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 False target_dir = self.video_record_le.text() + os.sep if not os.path.isdir(target_dir): msg_box = QMessageBox(QMessageBox.Information, '错误', '目录不存在') msg_box.exec_() return False return 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(): return target_dir = self.video_record_le.text() + os.sep command = 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_dir os.system(command) return 6. 篮球运动员检测视频处理 视频处理同样使用infer.py,不使用camera_id,使用video_file参数指定视频位置主要代码如下,先处理运动员检测,再处理篮球检测 def bsk_ply_dtc(self): if not self.check_store_path(): return target_dir = self.video_record_le.text() + os.sep tmp_dir = os.path.join(target_dir, 'tmp') if not os.path.isdir(tmp_dir): os.mkdir(tmp_dir) if not self.check_read_path(): return src_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_dir os.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_dir os.system(command)

如下图所示效果

7. 实现篮球和运动员分割 使用训练好的basketball_player_seg_640x640模型使用PaddleSeg中的infer.py def seg_video(self): if not self.check_store_path(): return target_path = self.video_record_le.text() + os.sep if not self.check_read_path(): return src_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: break cv2.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(): return src_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.8 while cap.isOpened(): # 画面暂留一段时间 time.sleep(wait_time) ret, frame = cap.read() if ret: cv2.imshow(name, frame) if cv2.waitKey(1) & 0xFF == ord('q'): break else: break cap.release() cv2.destroyWindow(name) def video_record(self): if not self.check_store_path(): return target_dir = self.video_record_le.text() + os.sep print('write video to ', target_dir) name = 'outcome.avi' target_path = target_dir + name cap = 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') break except Exception as e: print("video record failed:", e) cap.release() msg_box = QMessageBox(QMessageBox.Information, '错误', '视频录制失败') msg_box.exec_() return def 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') break except 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的推理速度。

此文章为搬运 原项目链接



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3