tensorflow图形检测_社交距离检测器——Tensorflow检测模型设计

在隔离期间,我花时间在github上探索Tensorflow的大量预训练模型。这样做时,我偶然发现了一个包含25 个带有性能和速度指标的预训练对象检测模型的存储库。拥有一些计算机视觉知识并给出了实际的背景知识,我认为使用其中之一来构建社交隔离应用程序可能会很有趣。

4a97df69259543cea0559290955a179f

更重要的是,上学期在计算机视觉课程中向我介绍了OpenCV,并意识到在执行许多小型项目时它的功能多么强大。其中之一包括执行图片的鸟瞰转换。一个鸟瞰图是一个基本场景的自上而下的表示。这是在构建自动驾驶汽车应用程序时经常执行的任务。

abd59801e060478da40275f9fec530d3

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

这使我意识到,将这种技术应用于我们想要监视社会距离的场景可以提高其质量。本文介绍了我如何使用深度学习模型以及计算机视觉方面的一些知识来构建强大的社交距离探测器。

本文的结构如下:

  • 选型
  • 人物检测
  • 鸟瞰图转换
  • 社会距离测量
  • 结果与改进

以下所有代码以及安装说明都可以在我的github存储库中找到。

1.选型

Tensorflow对象检测模型Zoo中可用的所有模型均已在COCO数据集(COntext中的通用对象)上进行了训练。该数据集包含120,000张图像,这些图像中总共有880,000个带标签的对象。这些模型经过训练可以检测此数据集中标记的90种不同类型的对象。所有这些不同对象的完整列表可在github repo的data部分访问的存储库的data部分中找到。这些对象包括汽车,牙刷,香蕉和人。

可用型号的非详尽清单

f8020816579741109a8f68e4b7485cbc

根据模型的速度,它们具有不同的性能。为了确定如何根据预测速度来利用模型的质量,我进行了一些测试。由于此应用程序的目标不是能够执行实时分析,因此我最终选择了fast_rcnn_inception_v2_coco ,它的mAP(验证集上的检测器性能)为28,非常强大,执行速度为58 ms 。

2.人员检测

要使用这种模型,为了检测人员,必须完成一些步骤:

  • 将包含模型的文件加载到张量流图中。并定义您要从模型获得的输出。
  • 对于每一帧,将图像通过图形以获取所需的输出。
  • 过滤掉不需要检测的弱预测和对象。

加载并启动模型

设计张量流模型的工作方式是使用图形。第一步意味着将模型加载到张量流图中。该图将包含为了获得所需检测而将要执行的不同操作。下一步是创建一个会话,该会话是负责执行上图中定义的操作的实体。有关图形和会话的更多说明,请参见此处。我决定实现一个类,以将与张量流图有关的所有数据保持在一起。

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 graph        with 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)

过滤掉弱预测和不相关的对象

aa01ae5a13c54d5390ab0ed997f943b8

人物检测结果

模型检测到的许多类之一是人。与一个人关联的类别为1。

为了排除弱预测(阈值:0.75)和除人以外的所有其他类别的对象,我使用了if语句,将这两个条件组合在一起以排除任何其他对象以进行进一步计算。

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

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

3.鸟瞰图转换

如引言中所述,执行鸟瞰图转换可为我们提供场景俯视图。值得庆幸的是,OpenCV具有强大的内置功能,可以将该方法应用于图像,以便将所拍摄的图像从透视图角度转换为顶视图。我使用了伟大的Adrian Rosebrock 的教程来了解如何做到这一点。

第一步涉及在原始图像上选择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 imagereturn : transformation matrix and the transformed image"""# Create an array out of the 4 corner pointscorner_points_array = np.float32(corner_points)# Create an array with the parameters (the dimensions) required to build the matriximg_params = np.float32([[0,0],[width,0],[0,height],[width,height]])# Compute and return the transformation matrixmatrix = 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 transformreturn : list containing all the new points"""# Compute the new coordinates of our pointslist_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 returnedtransformed_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库的function Combines ()函数,该函数允许在列表中获取所有可能的组合而无需保留双精度。在此堆栈溢出问题上对此进行了很好的解释。剩余部分是简单的数学运算:使用python中的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 chosen      if 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 red        change_color_topview(pair)        # Get the equivalent indexes of these points in the original frame and change the color to red        index_pt1 = list_indexes[i][0]        index_pt2 = list_indexes[i][1]        change_color_originalframe(index_pt1,index_pt2)

一旦确定两个点之间的距离太近,标记该点的圆圈的颜色将从绿色更改为红色,并且与原始帧上的边界框的颜色相同。

5.结果

让我回复一下该项目的工作方式:

  • 首先获取计划的4个角点,然后应用透视变换获得该计划的鸟瞰图并保存变换矩阵。
  • 获取原始帧中检测到的每个人的边界框。
  • 计算此框的最低点。这是位于双脚之间的点。
  • 使用转换矩阵对这些点中的每一个获取每个人的真实“ GPS”坐标。
  • 使用itertools.combinations()测量框架中每个点到所有其他点的距离。
  • 如果检测到社交距离冲突,请将边界框的颜色更改为红色。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329964.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode初级算法4.两个数组的交集 II

leetcode初级算法4.两个数组的交集 II 仅为个人刷题记录&#xff0c;不提供解题思路 题解与收获 我的解法&#xff1a;&#xff08;总结在代码中&#xff09; public int[] intersect(int[] nums1, int[] nums2) {//为空则返回if(nums1 null || nums2 null){return null;…

Java NIO:Buffer、Channel 和 Selector

转载自 Java NIO&#xff1a;Buffer、Channel 和 Selector本文将介绍 Java NIO 中三大组件 Buffer、Channel、Selector 的使用。 本来要一起介绍非阻塞 IO 和 JDK7 的异步 IO 的&#xff0c;不过因为之前的文章真的太长了&#xff0c;有点影响读者阅读&#xff0c;所以这里将它…

(转)使用IDEA将普通MAVEN项目转为WEB项目

转自&#xff1a; 使用IDEA将普通MAVEN项目转为WEB项目_yun0000000的博客-CSDN博客使用IDEA将普通MAVEN项目转为WEB项目https://blog.csdn.net/yun0000000/article/details/70664944 1、file--project Structure--,然后点“”号&#xff0c;,若没有war包&#xff0c;可修改mav…

python创建文件对象_python基础教程:文件读写

在Linux系统中&#xff0c;一切都是文件。但我们通常说的文件是保存在磁盘上的图片、文档、数据、程序等等。而在程序的IO操作中&#xff0c;很多时候就是从磁盘读写文件。本节我们讲解Python中的文件对象如何操作文件。创建文件对象 通过Python内置函数open()可以很容易的创建…

(转)springboot:添加JSP支持

转自&#xff1a; 14.springboot:添加JSP支持 - 简书&#xff08;1&#xff09;创建Maven web project 使用Eclipse新建一个Maven Web Project &#xff0c;项目取名为&#xff1a;spring-boot-jsp &#xff08;2&#xff09;在pom.xm...https://www.jianshu.com/p/4216bbd1e0…

leetcode初级算法5.加一

leetcode初级算法5.加一 仅为个人刷题记录&#xff0c;不提供解题思路 题解与收获 我的解法&#xff1a;&#xff08;总结在代码中&#xff09; public int[] plusOne(int[] digits) {//获取digits长度int length digits.length;//判断条件int count 0;//全是9的情况for …

epoll 浅析以及 nio 中的 Selector

转载自 epoll 浅析以及 nio 中的 Selector首先介绍下epoll的基本原理&#xff0c;网上有很多版本&#xff0c;这里选择一个个人觉得相对清晰的讲解&#xff08;详情见reference&#xff09;&#xff1a;首先我们来定义流的概念&#xff0c;一个流可以是文件&#xff0c;socket&…

转-SpringBoot——使用外置的Tomcat服务器

转自&#xff1a; SpringBoot——使用外置的Tomcat服务器_架构师的小跟班的博客-CSDN博客_springboot使用外置tomcat1 前言2 修改步骤2.1 修改打包方式&#xff08;jar -> war&#xff09;2.2 排除 SprignBoot的Web模块中的Tomcat依赖2.2.1 将嵌入的Tomcat依赖方式改成 pro…

leetcode初级算法6.字符串转整数(atoi)

leetcode初级算法6.字符串转整数(atoi) 仅为个人刷题记录&#xff0c;不提供解题思路 题解与收获 我的解法&#xff1a; public int myAtoi(String s) {//避免魔法值先设spaceString space " ";//如果是空或者是一串空字符串就滚回去&#xff01;if(s null || …

inner join on 加条件和where加条件_SQL学习笔记 - GROUP BY / JOIN / UNION

最近在DataCamp上学习SQL&#xff08;基于PostgreSQL&#xff09;的课程&#xff0c;本文主要记录自己易记混的点&#xff0c;以便日后参考学习&#xff0c;不做原理讲解。GROUP BY&#xff08;分组&#xff09;一般和聚合函数一起使用&#xff0c;包括COUNT()&#xff0c;AVG(…

Selector 实现原理

转载自 Selector 实现原理概述 Selector是NIO中实现I/O多路复用的关键类。Selector实现了通过一个线程管理多个Channel&#xff0c;从而管理多个网络连接的目的。 Channel代表这一个网络连接通道&#xff0c;我们可以将Channel注册到Selector中以实现Selector对其的管理。一个C…

转: 深入浅出-网络七层模型

转自 深入浅出&#xff0d;网络七层模型 - sunsky303 - 博客园引言 今天回顾一下&#xff0d;&#xff0d;网络七层模型&&网络数据包 网络基本概念 OSI模型 OSI 模型(Open System Interconnection model)是一个由国际标准化组织&#https://www.cnblogs.com/sunsky3…

date转timestamp格式_技术分享 | MySQL:timestamp 时区转换导致 CPU %sys 高的问题

作者&#xff1a;高鹏文章末尾有他著作的《深入理解 MySQL 主从原理 32 讲》&#xff0c;深入透彻理解 MySQL 主从&#xff0c;GTID 相关技术知识。本文为学习记录&#xff0c;可能有误请谅解。本文建议PC端观看&#xff0c;效果更佳。这个问题是一个朋友遇到的风云&#xff0c…

2021年最新springcloud配置中心不生效的版本原因

想直接看结论请到最下面&#xff0c;中间是我的纠错细节 实名吐槽一波cloudAlibaba文档。 github上的官方文档明明白白写着&#xff1a; 2.2.X版本适用于Springboot 2.2.X 彳亍&#xff01; 于是我将原本的2.6.0版本改成了SpringBoot 2.2.4Release&#xff0c;然后启动报错&a…

python爬新闻并保存csv_用python爬取内容怎么存入 csv 文件中

小白一个&#xff0c;爬取豆瓣电影250作为练习&#xff0c;想把爬取的内容用csv存储&#xff0c;想存但是不知道怎么自己原来代码拼接在一起。 ps:非伸手党&#xff0c;查阅了官方文档&#xff0c;也做了csv读写的练习&#xff0c;就是拼不到一起&#xff0c;不知道该怎么改。求…

idea部署springboot项目到外部tomcat

【README】 本文旨在记录idea部署springboot项目到外部tomcat的步骤&#xff1b; 第一次部署会踩很多坑儿&#xff0c;多查google&#xff0c;多重试&#xff1b; 第一次部署&#xff0c;不建议手动录入依赖&#xff0c;因为有可能遗漏&#xff1b;而且网络上资料很多但也很…

生成configDataContextRefres失败:Error creating bean with name ‘configDataContextRefresher‘

被这个问题折磨了很久&#xff0c;本人解决方法如下&#xff0c;奉劝一句&#xff0c;该看的官方文档还是要看&#xff0c;但是千万别傻傻地照做&#xff01; 首先编写bootstrap.properties&#xff0c;往里写入&#xff1a; 这些基础配置 然后检查自己是否引入了这个依赖&am…

python怎么用for循环找出最大值_用for循环语句写一个在输入的十个数字中求最大和最小值的python程序应该怎么写?...

“在输入的十个数字中求最大和最小值的 python 代码”这个需求&#xff0c;在不同时间来看&#xff0c;解题思路不同&#xff0c;所需要的 python 知识点不同。 作为萌新的我&#xff0c;为此特意整理了 3 种解法&#xff0c;以及相应的知识点笔记。 解法A&#xff1a;不使用列…

(转)mysql查看连接客户端ip和杀死进程

转自&#xff1a; mysql &#xff1a; show processlist 详解 - _小豪豪 - 博客园最近排查一些MySQL的问题&#xff0c;会经常用到 show processlist&#xff0c;所以在这里把这个命令总结一下&#xff0c;做个备忘&#xff0c;以备不时只需。 首先是几条常用的SQL。 1、按客户…

Java NIO学习笔记之图解ByteBuffer

转载自 Java NIO学习笔记之图解ByteBuffer ByteBuffer前前后后看过好几次了&#xff0c;实际使用也用了一些&#xff0c;总觉得条理不够清晰。 《程序员的思维修炼》一本书讲过&#xff0c;主动学习&#xff0c;要比单纯看资料效果来的好&#xff0c;所以干脆写个详细点的文章来…