本文将分享保存实时目标检测结果的方法,包括将目标信息逐帧保存到.txt文件中、逐帧输出检测结果图片、以及如何保存所有检测图片(包括视野中无目标的帧)。
目录
0.准备
1.目标信息保存
2.检测图片保存
3.保存所有帧
0.准备
本文以单摄像头实时目标检测进行演示,但是对多摄像头实时检测同样适用。如何进行实时检测这里就不再重复,详细的实现步骤可以看我之前写的博客:
使用YOLOv5实现单摄像头实时目标检测_Albert_yeager的博客-CSDN博客
使用YOLOv5实现多摄像头实时目标检测_Albert_yeager的博客-CSDN博客
1.目标信息保存
这个实际上是YOLOv5工程自带的功能,但是需要通过命令行的方式运行才能使用。在终端中运行下方指令,即可运行检测代码,并完成目标信息保存
python detect.py --weights yolov5s.pt --source 0 --save-txt
图中 1 是调用本地摄像头进行实时目标检测(可以改成USB摄像头或IP摄像头,具体看我之前的博客);2 是在pycharm中打开终端;3 是之前提到需要运行的指令。
有几个细节需要强调:终端运行后要点击一下实时检测窗口,按键盘上的 ‘q’ 结束检测,注意是在英文小写状态下按q,我在运行程序时输入法会自动切换到中文,这个时候按q是无效的,同时英文大写状态的Q也是无效的(因为q和Q的ASCII码值不同),当然这是代码设定的,可以改成别的字母结束。重要的是,只有通过这种方式,才能正常保存检测视频,如果直接关掉软件结束会使保存的视频文件无法打开。
运行完成后,会在.../runs/detect 文件目录下生成结果:
0.mp4 是实时检测的结果视频,labels中就是每帧的目标信息,以.txt格式保存(如果以60帧的速度运行,每秒就会生成60个.txt文件)。
随便打开一个文件,可以看到是个2行5列的矩阵,这表明检测到了2个目标,每一行表示对应目标的属性,第一列是标签名(就是训练的时候的类别标签序号,这里采用官方的yolov5s.pt进行检测,0对应‘person’),后面四列依次为xcenter ycenter w h(框中心的x、y坐标,以及框的宽、高),均为归一化数值。
2.检测图片保存
工程本身并不具有保存实时检测逐帧图片的功能,因此需要自行添加一些代码。
首先定义图片保存路径:
####################################保存实时检测图片################################
pic_dir = str(save_dir) + '/pic'
if not os.path.exists(pic_dir):
os.makedirs(pic_dir)
pic_path = pic_dir + '\\' + str(p.stem) + ('' if dataset.mode == 'image' else f'_{frame}')
##################################################################################
注意添加位置为detect()函数中位置定义部分:
然后添加帧保存代码
##############################只保存含目标的实时检测图片#################################
pic = (int(xyxy[0].item()) + int(xyxy[2].item())) / 2
if pic != 0:
cv2.imwrite(pic_path + f'{p.stem}.jpg', im0)
else:
im1 = cv2.imread('no.jpg', 1)
cv2.imwrite(pic_path + f'{p.stem}.jpg', im1)
#####################################################################################
注意添加位置为detect()函数中写结果部分:
仍然通过命令行运行代码(直接运行也能保存图片)这样既能保存标签又能保存图片,而且两者是相对应的,方便调用。
python detect.py --weights yolov5s.pt --source 0 --save-txt
运行后可以看到检测结果中有三个文件,标签、帧图片、实时检测视频。
pic文件夹中是所有包含目标的帧,可以发现,pic中图片数量和labels中标签数量相同,而且是一一对应的关系。
3.保存所有帧
上述方法只能保存包含目标的帧,这是因为保存相关的代码添加在for循环下,这就导致只有检测到目标,才会执行标签和帧图片的保存。因此如果要保存所有帧(不只是检测到目标的帧),必须将保存图片帧的代码提到for之外。
注释掉只保存含目标图片的代码(其实留着也行,如果需要目标出现时输出图片中带检测框的话建议留着)
添加代码:
# ##################################保存所有检测图片######################################
cv2.imwrite(pic_path + f'{p.stem}.jpg', im0)
# #####################################################################################
注意添加位置要在for之外(原因之前讲了)
仍然通过命令行运行代码(直接运行也能保存图片)这样既能保存标签又能保存图片。
python detect.py --weights yolov5s.pt --source 0 --save-txt
运行后可以看到检测结果中有三个文件,标签、帧图片、实时检测视频。
此时,pic文件夹中就包含了所有帧的图片(目标出现时不带检测框)。
再次说明,如果需要目标出现时输出图片中带检测框的话保留2中帧保存的代码即可(因为含目标的帧保存代码在3中保存代码之后执行,但保存图片的名称相同,因此会把不带检测框的图片覆盖掉)。
求学路上,你我共勉(๑•̀ㅂ•́)و✧