在本系列的上一篇文章中,我们已经在Raspberry Pi设备上启动了人体检测软件。在这一本文中,我们将比较Raspberry Pi 3B设备上的两种SSD模型(MobileNet和SqueezeNet),以提高准确性和性能。我们将选择一个更好的视频片段,以用于实时模式。
首先,让我们创建一个实用程序类,以评估函数执行的时间和FPS:
import time
class FPS:
def __init__(self):
self.frame_count = 0
self.elapsed_time = 0
def start(self):
self.start_time = time.time()
def stop(self):
self.stop_time = time.time()
self.frame_count += 1
self.elapsed_time += (self.stop_time-self.start_time)
def count(self):
return self.frame_count
def elapsed(self):
return self.elapsed_time
def fps(self):
if self.elapsed_time==0:
return 0
else:
return self.frame_count/self.elapsed_time
上面的类仅在调用start方法时保存执行的开始时间,并评估消耗的时间直到调用stop方法为止。知道总耗用时间和函数执行的次数,我们可以计算出较长计算过程的平均FPS。
现在,让我们修改Python代码以评估检测的检测时间(此处仅显示修改的部分):
fps = FPS();
fps.start()
obj_data = ssd.detect(image)
persons = ssd.get_objects(image, obj_data, person_class, 0.5)
fps.stop()
person_count = len(persons)
print("Person count on the image: "+str(person_count))
print("FPS: "+str(fps.fps()))
通过在几张图像上运行代码,我们可以估计设备的处理单元检测帧中人的平均时间。我们已经为MobileNet DNN模型完成了此操作,并且获得了1.25 FPS的平均值。这意味着设备可以在约0.8秒内处理一帧。
要测试SqueezeNet SSD模型,让我们再次修改代码。一个明显的变化是模型加载的路径:
proto_file = r"/home/pi/Desktop/PI_RPD/squeezenet.prototxt"
model_file = r"/home/pi/Desktop/PI_RPD/squeezenet.caffemodel"
另一个重要的修改是切换到具有不同缩放参数的帧处理器。SqueezeNet模型已经使用其自己的缩放系数进行了训练,因此我们必须为模型指定适当的值:
# frame processor for SqueezeNet
ssd_proc = FrameProcessor(proc_frame_size, 1.0, 127.5)
在用于MobileNet的相同图像上测试SqueezeNet模型,我们获得了略高的处理速度,约为1.5 FPS(或每帧约0.67秒)。看起来SqueezeNet模型比Raspberry Pi设备上的MobileNet更快。速度是主要问题,我们可能应该使用速度更快的模型。
但是在用术语或精度测试模型之前,我们不要得出结论。我们需要比较阳性检出率。为什么在这里很重要?当我们以实时模式测试人员检测时,这将是完全清楚的。显而易见的原因是,如果检测率很高,则在视频流上找到人的可能性就会增加。
要估计模型的检测率,我们应该针对许多图像运行代码并评估正确检测的次数。这是两个图像的实验结果:
如您所见,MobileNet SSD在两个图像上都发现了该人,并且报告的可能性很高——超过90%。SqueezeNet模型仅在其中一张图像上找到该人,置信度很低,只有57%。因此测试表明,使用SqueezeNet SSD进行人检测的可能性比MobileNet模型低约两倍。
考虑到速度估计和准确性评估这两个实验,我们宣布MobileNet DNN为最终获奖者。我们将对该模型进行所有进一步的实验。注意,如果我们改变主意,则所有代码都可以轻松地适用于SqueezeNet模型。
下一步
在本系列的下一篇文章中,我们将开发用于在视频流中进行人员检测的Python代码。它将使用OpenCV库从视频文件中读取帧。然后,我们将了解检测算法如何处理流数据以及如何将其适配于实时视频。