使用TensorFlow物体检测模型、Python和OpenCV的社交距离检测器

重磅干货,第一时间送达

0.介绍

疫情期间,我们在GitHub上搜索TensorFlow预训练模型,发现了一个包含25个物体检测预训练模型的库,并且这些预训练模型中包含其性能和速度指标。结合一定的计算机视觉知识,使用其中的模型来构建社交距离程序会很有趣。

学习OpenCV的过程中,小伙伴们应该知道对于一些小型项目OpenCV具有很强大的功能,其中一个就是对图片进行鸟瞰转换,鸟瞰图是对一个场景自上而下的表示,也是构建自动驾驶应用程序时经常需要执行的任务。

车载摄像头鸟瞰系统的实现

这说明将鸟瞰转换的技术应用到监视社交距离的场景中可以提高监视质量。

本期我们将介绍了如何使用深度学习模型以及计算机视觉方面的一些知识来构建强大的社交距离检测器。

本文的结构如下:

·模型选择

·人员检测

·鸟瞰图转换

·社交距离测量

·结果与改进

所有代码及安装说明可以以下链接中找到:https://github.com/basileroth75/covid-social-distancing-detection

1.模型选择

在TensorFlow物体检测模型zoo中的所有可用模型已经在COCO数据集(Context中的通用物体)上进行了预训练。COCO数据集包含120000张图像,这些图像中总共包含880000个带标签的物体。这些模型经过预训练可以检测90种不同类型的物体,物体类型的完整列表可以在GitHub的data部分得到,地址为:https://github.com/tensorflow/models/blob/master/research/object_detection/data/mscoco_complete_label_map.pbtxt

可用模型的非详尽清单

模型的预测速度不同,性能表现也不同。为了决定如何根据模型的预测速度来利用模型,我进行了一些测试。由于社交距离检测器的目标不是执行实时分析,因此最终选择了fast_rcnn_inception_v2_coco ,它的mAP(验证集上检测器的性能)为28,执行速度为58ms,非常强大,下载地址为:

http://download.tensorflow.org/models/object_detection/faster_rcnn_inception_v2_coco_2018_01_28.tar.gz

2.人员检测

使用上述模型检测人员,必须完成一些步骤:

·将包含模型的文件加载到TensorFlow图中,并定义我们想从模型获得的输出。

·对于每一帧,将图像输入到TensorFlow图以获取所需的输出。

·过滤掉弱预测和不需要检测的物体。

加载并启动模型:

TensorFlow模型的工作方式是使用graphs(图)。第一步意味着将模型加载到TensorFlow图中,该图将包含所需检测。下一步是创建一个session(会话),该会话是负责执行定义在图中操作的一个实体。有关图和会话的更多说明,参见https://danijar.com/what-is-a-tensorflow-session/ 。在这里我们实现了一个类,将与TensorFlow图有关的所有数据关联在一起。

class Model:""" Class that contains the model and all its functions """def __init__(self, model_path):""" Initialization function @ model_path : path to the model """
# Declare detection graph self.detection_graph = tf.Graph()# Load the model into the tensorflow graphwith self.detection_graph.as_default(): od_graph_def = tf.compat.v1.GraphDef()with tf.io.gfile.GFile(model_path, 'rb') as file: serialized_graph = file.read() od_graph_def.ParseFromString(serialized_graph) tf.import_graph_def(od_graph_def, name='')
# Create a session from the detection graph self.sess = tf.compat.v1.Session(graph=self.detection_graph)
def predict(self,img):""" Get the predicition results on 1 frame @ img : our img vector """# Expand dimensions since the model expects images to have shape: [1, None, None, 3] img_exp = np.expand_dims(img, axis=0)# Pass the inputs and outputs to the session to get the results (boxes, scores, classes) = self.sess.run([self.detection_graph.get_tensor_by_name('detection_boxes:0'), self.detection_graph.get_tensor_by_name('detection_scores:0'), self.detection_graph.get_tensor_by_name('detection_classes:0')],feed_dict={self.detection_graph.get_tensor_by_name('image_tensor:0'): img_exp})return (boxes, scores, classes)

通过模型传递每一帧

对于需要处理的每个帧,都会启动一个新会话,这是通过调用run()函数完成的。这样做时必须指定一些参数,这些参数包括模型所需的输入类型以及我们要从中获取的输出。在我们的案例中所需的输出如下:

·每个物体的边界框坐标

·每个预测的置信度(0到1)

·预测类别(0到90)

·过滤弱预测和不相关物体

人员检测结果

模型能检测到的很多物体类别,其中之一是人并且与其关联的类为1。为了排除弱预测(阈值:0.75)和除人以外的所有其他类别的物体,我使用了if语句,将这两个条件结合起来以排除任何其他物体,以免进一步计算。

if int(classes[i]) == 1 and scores[i] > 0.75

但是因为这些模型已经经过预训练,不可能仅检测此类(人)。因此,这些模型要花很长时间才能运行,因为它们试图识别场景中所有90种不同类型的物体。

3.鸟瞰图转换

如引言中所述,执行鸟瞰图转换可为我们提供场景的俯视图。值得庆幸的是OpenCV具有强大的内置函数,此函数可以将从透视图角度拍摄的图像转换为俯视图。我使用了Adrian Rosebrock的教程 来了解如何做到这一点:https://www.pyimagesearch.com/2014/08/25/4-point-opencv-getperspective-transform-example/

第一步选择原始图像上的4个点,这些点将成为要转换的图的角点。这些点必须形成一个矩形,至少两个相对的边平行,如果不这样做,则转换发生时的比例将不同。我已经在我的仓 库中 实现了一个脚本,该脚本使用OpenCV的setMouseCallback()函数来获取这些坐标。计算变换矩阵的函数还需要使用图像的image.shape属性计算图像尺寸。

width, height, _ = image.shape

这将返回宽度、高度和其他不相关的颜色像素值。让我们看看如何使用它们计算变换矩阵:

def compute_perspective_transform(corner_points,width,height,image):""" Compute the transformation matrix @ corner_points : 4 corner points selected from the image @ height, width : size of the image return : transformation matrix and the transformed image """# Create an array out of the 4 corner points corner_points_array = np.float32(corner_points)# Create an array with the parameters (the dimensions) required to build the matrix img_params = np.float32([[0,0],[width,0],[0,height],[width,height]])# Compute and return the transformation matrix matrix = cv2.getPerspectiveTransform(corner_points_array,img_params) img_transformed = cv2.warpPerspective(image,matrix,(width,height))return matrix,img_transformed

注意函数的返回值是矩阵,因为在下一步中将使用这个矩阵计算每个被检测到的人的新坐标,新坐标是帧中每个人的“ GPS”坐标,使用这些新坐标而不是使用原始基点结果更为准确,因为在透视图中当人们处于不同平面时,距离是不一样的,并且距相机的距离也不相同。与使用原始检测框中的点相比,这可以大大改善社会距离的测量。

对于检测到的每个人,将返回构建边界框所需的2个点,这两个点是边界框的左上角和右下角。通过获取两点之间的中点来计算边界框的质心,使用此结果,计算位于边界框底部中心的点的坐标,我认为这一点(称为“基点”)是图像中人坐标的最佳表示。

然后使用变换矩阵为每个检测到的基点计算变换后的坐标。在检测到人之后,在每一帧上使用cv2.perspectiveTransform()完成此操作。实现此任务的方式:

def compute_point_perspective_transformation(matrix,list_downoids):""" Apply the perspective transformation to every ground point which have been detected on the main frame. @ matrix : the 3x3 matrix @ list_downoids : list that contains the points to transform return : list containing all the new points """# Compute the new coordinates of our points list_points_to_detect = np.float32(list_downoids).reshape(-1, 1, 2) transformed_points = cv2.perspectiveTransform(list_points_to_detect, matrix)# Loop over the points and add them to the list that will be returned transformed_points_list = list()for i in range(0,transformed_points.shape[0]): transformed_points_list.append([transformed_points[i][0][0],transformed_points[i][0][1]])return transformed_points_list

4.社交距离测量

在每帧上调用此函数后,将返回一个包含所有新转换点的列表,从这个列表中,计算每对点之间的距离。这里我使用了itertools库的Combination()函数,该函数允许在列表中获取所有可能的组合而无需保留双精度。在https://stackoverflow.com/questions/104420/how-to-generate-all-permutations-of-a-list 堆栈溢出问题中对此进行了 很好的解释。其余的是简单的数学运算:使用math.sqrt()函数计算两点之间的距离。选择的阈值为120像素,因为它在我们的场景中大约等于2英尺。

# Check if 2 or more people have been detected (otherwise no need to detect)if len(transformed_downoids) >= 2: # Iterate over every possible 2 by 2 between the points combinations list_indexes = list(itertools.combinations(range(len(transformed_downoids)), 2))for i,pair in enumerate(itertools.combinations(transformed_downoids, r=2)): # Check if the distance between each combination of points is less than the minimum distance chosenif math.sqrt( (pair[0][0] - pair[1][0])**2 + (pair[0][1] - pair[1][1])**2 ) < int(distance_minimum): # Change the colors of the points that are too close from each other to redchange_color_topview(pair) # Get the equivalent indexes of these points in the original frame and change the color to redindex_pt1 = list_indexes[i][0]index_pt2 = list_indexes[i][1]change_color_originalframe(index_pt1,index_pt2)

一旦确定两个点之间的距离太近,标记该点的圆圈的颜色将从绿色更改为红色,原始框架上的边界框的颜色也做相同的颜色变换操作。

5.结果

回顾项目的工作原理:

·首先获取图的4个角点,然后应用透视变换获得该图的鸟瞰图并保存透视变换矩阵。

·获取原始帧中检测到的每个人的边界框。

·计算这些框的最低点,最低点是位于人双脚之间的点。

·对这些点应用变换矩阵,获取每一个人的真实“ GPS”坐标。

·使用itertools.combinations()测量帧中每个点到所有其它点的距离。

·如果检测到违反社交距离,将边框的颜色更改为红色。

我使用来自PETS2009 数据集http://www.cvg.reading.ac.uk/PETS2009/a.html#s0 的视频,该视频由包含不同人群活动的多传感器序列组成,它最初是为诸如人群中人员计数和密度估计之类的任务而构建的。我决定从第一个角度使用视频,因为它是最宽的一个,具有最佳的场景视角。该视频介绍了获得的结果:

https://youtu.be/3b2GPwN2_I0

6.结论与改进

如今,隔离以及其他基本卫生措施对抑制Covid-19的传播速度非常重要。但该项目仅是概念的证明,并且由于道德和隐私问题,不能用于监视公共或私人区域的社交距离。

这个项目存在一些小的缺陷,改进思路如下:

·使用更快的模型来执行实时社交距离分析。

·使用对遮挡更具鲁棒性的模型。

·自动校准是计算机视觉中一个众所周知的问题,可以在不同场景上极大地改善鸟瞰图的转换。

7.参考资料

https://towardsdatascience.com/analyse-a-soccer-game-using-tensorflow-object-detection-and-opencv-e321c230e8f2

https://www.pyimagesearch.com/2014/08/25/4-point-opencv-getperspective-transform-example/

https://developer.ridgerun.com/wiki/index.php?title=Birds_Eye_View/Introduction/Research

http://www.cvg.reading.ac.uk/PETS2009/a.html#s0

如果本文对小伙伴有帮助,希望可以在文末来个“一键三连”。

交流群

(0)

相关推荐

  • TensorFlow对象检测:训练,导出,优化,推断

    第1部分 从在自定义数据集中训练检测器到使用TensorFlow 1.15在Jetson纳米板或云上进行推理的详细步骤 完整代码可在GitHub上获得 TensorFlow对象检测API V2的教程可 ...

  • C 版本的 Opencv 调用 TensorFlow object detection API ...

    最近做的一个项目需要在c++程序中调用目标检测模型,但是在使用opencv调用模型时总是遇到各种各样的错误,一直没有成功.最近终于打通了这一过程,总结如下(本文以SSD_MobileNet模型为例). ...

  • OpenCV4.0 Mask RCNN 实例分割示例 C++/Python实现

    前几天OpenCV4.0-Alpha发布,其中新增实例分割Mask RCNN模型是这次发布的亮点之一. 图像实例分割即将图像中目标检测出来并进行像素级分割. 昨天learnopencv.com博主Sa ...

  • Tensorflow objection detection api 物体检测模型 (三) 从...

    在利用官方提供的Tensorflow objection detection api 进行物体检测时,会有很多物体被检测出来并且被框柱,而我的目标是只需要一个类别的物体,那么如何将这个特定的物体抠出来 ...

  • 使用tensorflow做特定目标检测

    使用tensorflow做目标检测 概述 更改代码 概述 最近博主参加一个小比赛,需要用到目标检测从而进行固定位置的人物经检查,看某位置是否有人,和行人检测不同,大部分的人是坐着的,而且被遮挡的比较多 ...

  • 手把手教你训练自己的Mask R

    近来在学习图像分割的相关算法,准备试试看Mask R-CNN的效果. 关于Mask R-CNN的详细理论说明,可以参见原作论文https://arxiv.org/abs/1703.06870,网上也有 ...

  • Open3d学习计划—高级篇 4(多视角点云配准)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  • tensorflow C 调用maskrcnn和opencv4.11 调用maskrcnn

    先说个大概,opencv是intel的所以不支持竞争对手的功能(nvidia的gpu),那个OPENCL选项其实是intel的核显,比cpu调用还慢,加速功能要自己写,没有gpu的可以用一下,速度在2 ...

  • 基于OpenCV实战:动态物体检测

    重磅干货,第一时间送达 最近,闭路电视安全系统运行着多种算法来确保安全,例如面部识别,物体检测,盗窃检测,火灾警报等.我们在运动检测的基础上实现了许多算法,因为在空闲帧上运行所有这些进程没有任何意义. ...

  • 用OpenCV实现超轻量的NanoDet目标检测模型!

    作者丨nihate 审稿丨邓富城 编辑丨极市平台 极市导读 本文作者用OpenCV部署了超轻量目标检测模型NanoDet,并实现了C++和Python两个版本,并对此进行了解析,附完整代码. > ...

  • 计算机视觉物体检测中面对的挑战

    导读 给出了目前目标检测中的一些问题和挑战. 几年前,在图像中寻找并分类单个物体是一项极其困难的任务.今天,在计算机视觉的帮助下,数字设备可以简单快速地识别图像的内容,这为不同领域的视觉数据理解和分析 ...

  • 雷达科普|自动驾驶毫米波雷达物体检测技术-算法

    导读: 本文的代码均在MATLAB上运行, MATLAB在传统辅助驾驶系统的验证和模拟上相对于其他编程语言具有很强的优势. Range and velocity estimation 在这篇文章中, ...

  • 用于孤独症小鼠模型的行为检测方法(1):社交互动和社交沟通检测

    孤独症( autism) 是一种复杂的神经发育障碍性疾病,具 有很高的遗传性,全球人群发病率为 0. 6% - 1. 0% ,男女比 例接近 4∶1.鉴于孤独症患病率的上升及其产生的不良社 会影响,急 ...

  • 用于孤独症小鼠模型的行为检测方法(2):社交沟通检测

    孤独症交流沟通障碍在人类主要表现为语言的理解和 使用方面发育迟缓,早期不能正常对话,缺乏节奏和韵律,语言乏力等,孤独症模型鼠的交流沟通障碍也被用于研究人类的相关症状.目前认为嗅觉机制是小鼠交流沟通的主 ...

  • 使用Transformer来做物体检测

    作者:Jacob Briones(编译:ronghuaiyang) 来源:AI公园 著作权归作者所有,本文仅作学术分享,若侵权,请联系后台删文处理 导读 这是一个Facebook的目标检测Transf ...

  • 广西大学郑含博、李金恒 等:基于改进YOLOv3的电力设备红外目标检测模型

    EVS34圆桌论坛议程:动力电池技术 EVS34圆桌论坛议程:燃料电池商用车发展趋势 EVS34主题论坛议程:智能充换电.充换电基础设施及车网互动 EVS34圆桌论坛议程:下一代电力电子(SiC) E ...