65.9K
CodeProject 正在变化。 阅读更多。
Home

AI 社交距离检测器:找出距离过近的人

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2020年12月10日

CPOL

3分钟阅读

viewsIcon

6328

downloadIcon

155

在本文中,我们将使用这些中心来估计人与人之间的距离,并指出距离过近的人。

在本文中,我们将继续开发一个用于AI驱动的社交距离检测器的Python控制台应用程序。 在学习了如何检测图像中人物的位置后,我们准备计算它们之间的距离,并指出哪些人彼此过于接近。

如下图所示,如果两个人之间的距离低于预定义的阈值,则将用红色矩形框出这些人。完整的配套代码在这里

计算两点之间的距离

我们首先创建一个方法来计算两个人之间的距离。为此,我们计算两个边界框中心之间的欧几里得距离。

def calculate_distance_between_rectangle_centers(rect_center_1, rect_center_2):        
    # Calculate absolute difference between x and y coordinates
    x_abs_diff = abs(rect_center_1[0] - rect_center_2[0])
    y_abs_diff = abs(rect_center_1[1] - rect_center_2[1])
 
    # Calculate Euclidean distance
    return math.sqrt(x_abs_diff**2 + y_abs_diff**2)

上面的函数是distance_analyzer模块的静态方法(请参阅Part_06文件夹中的distance_analyzer.py)。

查找距离过近的人

要找到距离过近的人,我们需要检查每个人之间的距离。 实际上,我们需要执行一个双重循环。但是,第ith个人和第jth个人之间的距离与第jth个人和第ith个人之间的距离相同。因此,嵌套for循环中的迭代次数可以从j = 1..N减少到j = i + 1..N。 这是方法的完整实现,该方法给定检测到的人员列表,找到那些距离过近的人(另请参见distance_analyzer.py

def find_people_that_are_too_close(detection_results, distance_threshold):        
    # Prepare results' list
    results = []
 
    # Get rectangle centers
    rectangle_centers = DistanceAnalyzer.get_rectangle_centers(detection_results)        
 
    # Analyze distance between each object
    N = len(detection_results)
    for i in range(N):
        for j in range(i+1, N):                
            rect_center_1 = rectangle_centers[i]
            rect_center_2 = rectangle_centers[j]
 
            distance = DistanceAnalyzer.calculate_distance_between_rectangle_centers(
                rect_center_1, rect_center_2)
 
            # If distance between objects is too close
            # append centers to the results' list
            if(distance <= distance_threshold):
                results.append((detection_results[i]['rectangle'],
                    detection_results[j]['rectangle']))
 
    return results

该方法接受两个参数

  • detection_results – AI模型返回的已检测到人员的列表。 请注意,该列表中的每个元素都包含一个对象,该对象包含检测分数,边界框和标签。
  • distance_threshold – 指定图像中人员可以有多近(以像素为单位测量)。 如果计算出的人员之间的距离小于此值,则会将边界框添加到返回的results列表中。

给定输入参数,该方法找到边界框的中心,然后计算它们之间的距离。 它返回围绕距离过近的人的矩形。 让我们看看如何在图像中显示这些矩形。

显示谁没有保持社交距离

为了指示距离过近的人,我们可以使用OpenCV的rectangle函数,如前所述。 该代码可能与我们用于绘制图像中检测到的对象的边界框和标签的代码非常相似。 但是,作为输入,我们采用find_people_that_are_too_close返回的列表。 请记住,该方法返回一个列表,其中每个元素包含两个矩形。 这些矩形是违反社交距离规则(distance_threshold)的人员的边界框。

我们需要遍历该列表中的元素并一次显示两个矩形(请参阅Part_03中的image_helper模块)

def indicate_people_that_are_too_close(image, people_that_are_too_close, delay=0):
    # Prepare window
    opencv.namedWindow(common.WINDOW_NAME, opencv.WINDOW_GUI_NORMAL)
 
    # Iterate over objects (that is a pair of rectangle_points)
    for i in range(len(people_that_are_too_close)):
        
        # Draw each rectangle
        for j in range(len(people_that_are_too_close[i])):
            rectangle_points = people_that_are_too_close[i][j]
 
            opencv.rectangle(image, rectangle_points[0], rectangle_points[1], 
                common.RED, common.LINE_THICKNESS)
    
    # Display image
    opencv.imshow(common.WINDOW_NAME, image)
        
    # Wait until the user presses any key
    opencv.waitKey(delay)

如上所示,我们使用namedWindow函数创建窗口,并使用imshow显示图像。 其他组件与指示检测到的对象的情况几乎相同。

整合

有了以上所有内容,我们可以创建如下主脚本(请参阅Part_07文件夹中的main.py

import sys
sys.path.insert(1, '../Part_03/')
sys.path.insert(1, '../Part_05/')
sys.path.insert(1, '../Part_06/')
 
from inference import Inference as model
from image_helper import ImageHelper as imgHelper
from video_reader import VideoReader as videoReader
from distance_analyzer import DistanceAnalyzer as analyzer
 
if __name__ == "__main__": 
    # Load and prepare model
    model_file_path = '../Models/01_model.tflite'
    labels_file_path = '../Models/02_labels.txt'
 
    # Initialize model
    ai_model = model(model_file_path, labels_file_path)    
 
    # Initialize video reader
    video_file_path = '../Videos/01.mp4'
    video_reader = videoReader(video_file_path)
 
    # Detection and preview parameters
    score_threshold = 0.4
    delay_between_frames = 5
 
    # Perform object detection in the video sequence
    while(True):
        # Get frame from the video file
        frame = video_reader.read_next_frame()
 
        # If frame is None, then break the loop
        if(frame is None):
            break
        
        # Perform detection         
        results = ai_model.detect_people(frame, score_threshold) 
 
        # Find people that are too close
        proximity_distance_threshold = 50
        people_that_are_too_close = analyzer.find_people_that_are_too_close(
            results, proximity_distance_threshold)
 
        # Indicate those objects in the image       
        imgHelper.indicate_people_that_are_too_close(
            frame, people_that_are_too_close, delay_between_frames)

该脚本设置AI模型,打开示例视频文件,然后找到距离过近的人。 在这里,我将距离阈值设置为50像素。您可以自由尝试此参数。运行main.py之后,您将获得简介中显示的结果。

总结

我们终于将AI模型与查找违反社交距离规则的人的计算联系起来。 但是,我们一直在使用的模型不是很健壮,有时该解决方案无法正确指示距离过近的人。 我们将在最后一篇文章中通过合并最先进的YOLO检测器来解决此问题。

© . All rights reserved.