Обработка видео

В данной демонстрации посмотрим, что можно сделать с видео посредством Engee. Для этого поработаем с видеороликом, взятым из Интернета. Видео представлено ниже.

Pkg.add("VideoIO") # Библиотека обработки видеопотока
   Resolving package versions...
  No Changes to `/user/.project/Project.toml`
  No Changes to `/user/.project/Manifest.toml`
using VideoIO # Библиотека обработки видео
using ImageShow # Библиотека отрисовки изображений
using StackViews # Библиотека обработки множеств
using ImageFiltering # Библиотека фильтрации изображений

Далее, используя функцию VideoIO.load, загружаем имя файла в память как вектор массивов изображений. А при помощи StackView мы выполним преобразования вектора в многомерную матрицу.

path = @__DIR__ # Возвращает путь до папки открытой в файловом менеджере
path_video = "$path/input.mp4"
"/user/start/examples/image_processing/video_processing/input.mp4"
vid = VideoIO.load( path_video )
Stack = StackView(vid)# Сборка вектора изображений в матрицу
simshow(Stack[:,:,1])# Отрисовка первого кадра видео

interactive-scripts/images/image_processing_demo_video_processing/07476683c755503e2825176143f2ccf5f1b879d8

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

Функция get_time_duration возвращает дату и время начала, а также продолжительность видеофайла. Обратите внимание: если дата и время отсутствуют, то функция вернёт 00:00 1 января 1970 г..

Также мы можем узнать размерности кадров и их количество, используя функцию size для стека изображений.

get_time = VideoIO.get_time_duration(path_video)
(DateTime("1970-01-01T00:00:00"), 6.016)
print("All size video: " * string(size(Stack)))
All size video: (720, 1280, 180)
print("FPS: " * string(size(Stack,3)/floor(get_time[2])))
FPS: 30.0

Обрежем видео, оставив только центральную его часть.

new_video = Stack[1:360,1:640,:]

for i in 1:size(Stack,3)
new_video[:,:,i] = Stack[180:180+359,320:320+639,i]
end

simshow(new_video[:,:,1])# Отрисовка первого кадра видео

interactive-scripts/images/image_processing_demo_video_processing/02d9f4cc481d45396d38c2c832059356e4a45436

Теперь на первые 100 кадров обрезанного видео добавим фильтрацию для создания эффекта размытия.

for i in 1:100
new_video[:,:,i] = imfilter(new_video[:,:,i], Kernel.gaussian(3))
end

simshow(new_video[:,:,1])# Отрисовка первого кадра видео

interactive-scripts/images/image_processing_demo_video_processing/067d496325a0f5309c903867192a069b7f3b551a

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

video = [zeros(eltype(new_video), size(new_video, 1), size(new_video, 2)) for _ in axes(new_video, 3)]

@inbounds for k in axes(new_video, 3)
       video[k] = new_video[:,:,k]
end
Цель encoder_options

Перцептивное сжатие, по умолчанию h264. Лучшее решение для большинства случаев

(crf=23, preset="medium")

Сжатие без потерь. Самый быстрый, самый большой размер файла

(crf=0, preset="ultrafast")

Сжатие без потерь. Самый медленный, минимальный размер файла

(crf=0, preset="veryslow")

Прямое управление битрейтом и частотой внутри кадров

(bit_rate = 400000, gop_size = 10, max_b_frames = 1)

encoder_options = (crf=23, preset="medium")
VideoIO.save("video.mp4", video, framerate=30, encoder_options=encoder_options)

Вывод

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