Пока мы находимся в самом разгаре 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!