Время прочтения: 4 мин.

В аудиторской деятельности мы все чаще в своей работе стали обращаться к материалам камер видеонаблюдения с целью выявления отклонений в обеспечивающих процессах организации. В век высоких технологий анализ огромного объема видео осуществляется с применением различных IT инструментов, в ходе которого на первом этапе производятся действия по кадрированию (формированию фреймов) видео.

Для себя были выделены два инструмента Computer Vision, которые можно использовать для решения нашей задачи: OpenCV, MoviePy.

В тестах будут использованы:

— компьютер мощностью (Intel(R) Core(TM) i3-8109U CPU @ 3.00GHz   3.00 GHz0);

—  видео формата mp4 объемом 128,72 МБ, продолжительностью 9 мин. 30 сек. (570 сек.).

В ходе кадрирования мы будем получать по 24 кадра в секунду. По итогам каждого прогона мы получим на выходе порядка 13,68 тыс. файлов, которые будут сохранены в отдельно созданные папки.

OpenCV

Устанавливаем необходимые библиотеки:

import cv2
import os

Загружаем видео и создаем папку с названием клипа, для дальнейшего сохранения в нее фреймов.

cam = cv2.VideoCapture("Путешествие муравья.mp4")
os.makedirs('data')

Запускаем процесс формирования фреймов с сохранением полученных кадров в созданной ранее папке. В данном случае при обработке 1 секунды видео будет сформировано по 24 фрейма.

%%time
#необходимо для подсчета времени, затраченное на кадрирование видео
currentframe = 0
while(True):
    ret,frame = cam.read()
    if ret:
        name = './data/frame' + str(currentframe) + '.jpg'
        cv2.imwrite(name, frame)
        currentframe += 1
    else:
        break

Фиксируем время выполнения кода. Wall time: 18min 15s

MoviePy

Устанавливаем необходимые библиотеки:

from moviepy.editor import VideoFileClip
import numpy as np
import os
from datetime import timedelta

Загружаем видео и создаем папку с названием клипа, для дальнейшего сохранения в нее фреймов.

video_file = 'Путешествие муравья.mp4'
video_clip = VideoFileClip(video_file)
filename, _ = os.path.splitext(video_file)
if not os.path.isdir(filename):
    os.mkdir(filename)

Функция format_timedelta() принимает объект timedelta и возвращает строковое отображение временной точки видео, в момент которого формируется кадр. В дальнейшем результат выполнения функции будет использован при формировании названия сохраняемого фрейма.

def format_timedelta(td):
    result = str(td)
    try:
        result, ms = result.split(".") 
    except ValueError:
        return result + ".00".replace(":", "-")
    ms = int(ms)
    ms = round(ms / 1e4)
    return f"{result}.{ms:02}".replace(":", "-")

Формируем фреймы с определением шага формирования изображения в переменной step. Сохраняем результат в сформированной ранее папке:

%%time
step = 1/24
#данное значение переменной step определяет шаг кадрирования, соответствующее частоте кадров в видео (24 кадр в секунду)
for current_duration in np.arange(0, video_clip.duration, step):
    frame_duration_formatted = format_timedelta(timedelta(seconds=current_duration)).replace(":", "-")
    frame_filename = os.path.join(filename, f"frame{frame_duration_formatted}.jpg")
    video_clip.save_frame(frame_filename, current_duration)  

Фиксируем время отработки кода: Wall time: 11min 55s

Подведем итоги произведенных нами тестов CV инструментов в сводную таблицу.

Инструмент кадрированияПродолжительность работы, мин.сек.Общий размер формированных изображений, ГБ
OpenCV4 мин. 22 сек.1.99
MoviePy2 мин. 00 сек.0.86

Как видим оба инструмента можно использовать при решении нашей задачи. Однако, OpenCV затрачивает больше времени на выполнение задачи и требует выделения дополнительных объемов памяти для сохранения фреймов, а MoviePy.выполнит задачу за меньший промежуток времени и с меньшим использованием дискового пространства.

Для чистоты эксперимента было проведено еще несколько тестов на основе нашего видео, конвертированного и сохраненного посредством внешней программы в разных форматах (avi, mpg, mkv). Ниже итоги тестов:

Формат видеоРазмер видео после конвертации, ГБOpenCVMoviePy
Продолжительность работы, мин. сек.Общий размер формированных изображений, ГБПродолжительность рабты, мин. сек.Общий размер формированных изображений, ГБ
.avi0.319 мин. 31 сек.3.814 мин. 23 сек.1.44
.mpg0.282 мин. 31 сек.1.011 мин. 43 сек.0.5
.mkv0.094 мин. 45 сек.1.822 мин. 8 сек.0.83

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

Следует обратить внимание, что наилучшие показатели производительности инструментов получены при работе с файлом в формате .mpg. Время кадрирования для OpenCV оптимизировано на 50%, для MoviePy на 14%.

 P.S. Через изменение частоты кадрирования видео вы можете значительно ускорить формирование фреймов.

В нашем коде кадрирование соответствует частоте кадров в видео (24-кадра в секунду). В ряде случаев такая частота кадрирования является избыточной, например, при обработке полученных изображений для детекции людей, животных, машин и прочих предметов. Это непосредственно влияет на продолжительность работы инструмента кадрирования и размеры памяти для хранения фреймов.

Путем нехитрых манипуляций мы можем уменьшить частоту формирования фреймов до 1 кадр в секунду:

Для OpenCV

currentframe = 0
while(True):
    ret,frame = cam.read()
    if ret & (currentframe%24==0):
        name = './data/frame' + str(currentframe) + '.jpg'
        cv2.imwrite(name, frame)
    currentframe += 1
    if ret:
        continue
    else:
        break

Для MoviePy

В уже написанном выше коде для переменной step определяем значение, равное 1.

Подобьем итоги произведенных нами действий по уменьшению частоты кадрирования:

Инструмент кадрированияЧастота кадрирования 24 кадра в сек.Частота кадрирования 1 кадр в сек.
Продолжительность работы, мин. сек.Общий размер формированных сообщений, ГБПродолжительность работы, мин. сек.Общий размер формированных сообщений, ГБ
OpenCV4 мин. 22 сек.1.990 мин. 43 сек.0.09
MoviePy2 мин. 0 сек.0.860 мин. 20 сек.0.04

Таким образом, при установлении кадровой частоты извлечения изображений из видео с периодичностью 1 фрейм в секунду при обработке исходного видео вместо 13,68 тыс. изображений на выходе получим всего 0,57 тыс. кадров, что повышаем производительность инструментов Computer Vision в 6 раз.