Пока мы находимся в самом разгаре COVD-19, и скоро его ожидает конец, создание основы для поддержания социального дистанцирования может оказаться полезным, если аналогичные сценарии возникнут в будущем. В настоящее время не существует системы, которая могла бы уведомлять людей о возможности посещения определенных общественных мест или о том, что они в настоящее время работают в условиях социального дистанцирования.

Используя ImageAI, OpenCv, Numpy и Matplotlib, я создал модель обнаружения объектов, которая идентифицировала людей в видеоканале и использовала эвклидово расстояние и порог, чтобы определить, были ли они дистанцированы от общества. Затем эти данные были собраны и нанесены на график, чтобы показать расстояния между центроидами и их общее движение по отношению к другим центроидам.

Создание структуры, позволяющей измерить территорию и определить, практикуется ли социальное дистанцирование или скопились ли толпы людей, казалось интересным и актуальным проектом. Этот проект можно не только расширить для создания системы мониторинга, но также можно использовать для анализа того, как микробы и болезни могут распространяться при перемещении людей и их взаимодействии в толпе.

Сначала давайте импортируем необходимые библиотеки

from imageai.Detection import VideoObjectDetection
import os
import numpy as np
import cv2
import matplotlib.pyplot as plt

Затем мы создаем нашу модель ObjDetection, больше о том, как это сделать, и другие руководства по ImageAI и его функциям можно найти здесь: http://imageai.org

Execution_path возвращает текущий каталог, в котором мы работаем, мы используем его, чтобы указать путь к нашему каталогу результатов, нашей модели, входному файлу и выходному файлу. ImageAI позволяет вам объявить, какой настраиваемый объект вы хотите обнаруживать, например автомобили, магазины, автобусы и т. Д., А также позволяет вводить функцию, которая будет выполняться для каждого кадра (per_frame_function). Мы создадим функцию per_frame_function с именем dist_func, которая вычисляет эвклидово расстояние между центроидами и устанавливает порог.

execution_path = os.getcwd()
results_dir = os.path.join(execution_path, 'Results/')
detector = VideoObjectDetection()
detector.setModelTypeAsYOLOv3()
detector.setModelPath(os.path.join(execution_path, 'yolo.h5'))
detector.loadModel()
custom = detector.CustomObjects(person=True)
detection = detector.detectCustomObjectsFromVideo(custom_objects=custom,
                                              input_file_path=os.path.join(execution_path,'traffic-mini.mp4'),
                                                  output_file_path=os.path.join(execution_path,'OUTPUT4.mp4'),
                                                  frames_per_second=30, per_frame_function=dist_func,
                                             minimum_percentage_probability=60,log_progress=True)

Давайте пройдемся по нашему dist_func.

data = []
def dist_func(counting, output_objects_array,output_objects_count):
     a =[]
     points =[]
     for d in output_objects_array:
         x1 = d['box_points'][0]
         y1 = d['box_points'][1]
         x2 = d['box_points'][2]
         y2 = d['box_points'][3]
         centroid = (int((x1 + x2) / 2), int((y1 + y2) / 2))
         #print(type(centroid))
         a.append(centroid)
     for i in range(len(a)):
         for j in range(i+1, len(a)):
            distance = euc_dist(a[i],a[j])
            if distance > find_dist_ratio(x1, y1):
                print('Social Distancing Not Maintained')
                pair1 = []
                pair2 = []
                x, y = a[i]
                x2, y2 = a[j]
                pair1.append(x)
                pair1.append(y)
                pair2.append(x2)
                pair2.append(y2)
                points.append([pair1, pair2])
     data.append(points)

Dist_func принимает количество кадров, output_objects_array и output_objects_count, больше о том, что это такое, можно найти в документации ImageAI. Массив output_objects_array ImageAI содержит все обнаруженные объекты в кадре, их процент вероятности и координаты точки прямоугольника. Мы перебираем каждый объект в output_objects_array и используем его box_points для вычисления его центроида. Мы перебираем все объекты и добавляем все центроиды в массив «a».

Затем мы перебираем массив «a», используя два цикла for, чтобы вычислить евклидово расстояние между каждой комбинацией пар центроидов. В этом случае, не зная соотношений расстояний, мы используем среднюю точку между ограниченным прямоугольником в качестве порогового значения (логика состоит в том, что средний рост человека составляет более 5 футов, в результате получается средняя точка ограниченного прямоугольника (x1-y1) идентифицированного объекта (человека ) должен служить порогом расстояния между центроидами для социального дистанцирования). Логика элементарная, но работает для наших целей: если пара центроидов соответствует этому критерию, мы добавляем x-значения обоих центроидов в список и делаем то же самое с y-значениями. Затем мы добавляем эти два списка как список к другим спискам (мы любим вложенные списки!), А затем добавляем эти списки в пустой список вне функции. Таким образом, к концу кадров у нас есть список с двойным вложением, состоящий из пар центроидов для каждого кадра.

Примерно так: [[[3,4], [7,8]], [[8,4], [6,8]]], [[[3,4], [7,8]], [[8,4], [6,8]]]]

После того, как мы сделаем это и получим список списков соприкасающихся пар центроидов, теперь мы можем их визуализировать!

Я смог использовать matplotlib для построения графиков взаимодействий центроидов, построив пары центроидов для каждого кадра и используя OpenCV VideoWriter для создания «фильма» движений центроидов.

В контексте микробов, болезней и социального дистанцирования интересно почти отобразить контакт, который может иметь один человек в толпе людей, а также отобразить взаимодействие с окружающими.

Весь мой код можно найти на моем GitHub! Https://github.com/vmarar/ObjDetect

Спасибо за прочтение!

Примечание от In Plain English

Вы знали, что у нас четыре публикации и канал на YouTube? Вы можете найти все это на нашей домашней странице plainenglish.io - проявите немного любви, подписавшись на наши публикации и подписавшись на наш канал YouTube!