实时对象检测是一个非常有趣的话题。 我们应如何可靠地检测视频输入中的人和其他现实生活中的物体? 最近我设法构建了一个非常简单的应用程序,只需连接到用户的电脑网络摄像头就可自动检测对象。 我想与大家分享一下我是如何构建这个应用程序以及我在此过程中遇到的一些有趣的问题和挑战。
项目的源代码可以在这里找到(https://github.com/schumanzhang/object_detection_real_time )。
对象检测是计算机视觉领域非常活跃的研究课题。 在图像中检测和定位对象(可理解为在对象周围放置边界框)最有效的方法是使用深度学习技术。有几种特意为此目的设计的神经网络架构,例如 R-CNN, 快速 R-CNN,单次检测(SSD)和 YOLO(You Only Look Once)。
Tensorflow 对象检测模型
你可以在 tensorflow 库中轻松找到上述神经网络架构的预训练模型。它们统称为 tensorflow 检测模型集合。这些预训练模型在 COCO 数据集上进行训练(https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md),包含总共90类标签(现实世界的对象,如人,猫和狗等)。在这个简单的应用程序中,我们将使用被称为 mobilenet 的单次检测方法。这种架构更紧凑并可以获得额外的速度提升,这对分析每秒30-50帧图像来说很重要。
我不会详细介绍这些神经网络如何工作(这是另一个独立而有趣的话题)。 在我们的应用程序中,我们的重点是检测人员,我们正试图回答房间里是否有人的问题,如果是,有多少人? 但它也应该能检测多达90个现实世界的对象类别,包括手机,书籍,笔记本电脑等普通物体。理论上,我们可以使用迁移学习方法来重新训练这些神经网络架构的最后几层,以便检测更多种类的物体,但是这需要额外的训练数据,以及大量的计算能力和时间。
简单来说,我们的视频流分析将使用 tensorflow,open-cv 和 Python 检测房间中的人员。
构建对象检测应用程序
该应用程序的整体流程如下:
我们将使用 open-cv Python 库从笔记本电脑的网络摄像头中读取帧数据。这将通过 open-cv 中的 VideoCapture 函数完成。
然后我们将这些帧传递到 mobilenet ssd 模型中以检测对象。置信水平高于0.5的任何检测都将被返回并绘制到帧图像中。
任何检测到的对象都将通过可视化模块,在图像中检测到的对象周围放置彩色边界框。
我们还添加了一个跟踪模块,用于显示房间是否为空以及房间内的人数。这些数据将被存储在单独的.csv 文件中。
处理后的帧数据回传后,我们可以使用 open-cv 中的 imshow 函数向用户显示带边界框的帧图像。
最后,视频流的输出将以每秒20帧的速率写入单独的.mp4 文件中,以便后期可以欣赏我们的工作 :)
在上面的代码中,'while' 循环用于从网络摄像头读取帧数据,之后将未处理的帧数据放入输入队列以传递给我们的深度学习模型。 一旦我们得到 tensorflow 的预测结果,这些预测/检测值将被插入到输出队列中,然后通过 object_tracker 类的可视化模块,最后我们将处理后的帧写入单独的文件并将结果显示给用户。
我们将利用 Python 中的多线程来提高处理视频帧的速度。 下面的 worker 函数将从输入队列中获取帧数据,加载 tensorflow 模型并将任何检测结果传回输出队列。 这是与主线程分开运行的。
当然,为了可视化检测,我们需要传递检测到的类标签,它们各自的置信度,边界框颜色和坐标,并将它们绘制到帧图像上。
测试及评估应用程序
接下来的问题是这个简单的应用程序表现如何? 在我的笔记本电脑上运行应用程序我觉得检测人员功能表现还不错。 我没有将这些应用程序置于严格的测试环境中。 但是,我也看到了很多表现相当脆弱的情况。 首先,当我把史蒂夫·乔布斯的传记放在镜头前时,它会检测成另一个人,而不是一本书(因此无法区分真人或某人的图像)。 其次,我觉得在检测人员表现良好的同时,检测其他类别的表现并不是特别好,比如经常会将我的手机误认为是电视或笔记本电脑。 在检测现实世界的其他物体时还有很大的改进空间。
潜在的现实应用案例?
我们可以很容易地想到许多有趣的现实应用案例,用于分析和检测实时视频流中的人员或其他物体。 我们可以在监控摄像头中检测到人员的存在,毕竟我们有大量的被忽视的安防摄像头。我们可以让摄像机跟踪人员,计算人流量,甚至可以实时识别特定的行为。 自动运输也即将出现,这种技术对于帮助我们的车辆看到道路和探测行人至关重要。