Engee documentation
Notebook

Video processing

In this demo, let's see what you can do with a video using Engee. To do this, let's work with a video clip taken from the Internet. The video is presented below.

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

Next, using the VideoIO.load function, we load the file name into memory as a vector of image arrays. And using StackView, we will perform vector transformations into a multidimensional matrix.

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

From the resulting matrix, we can calculate the frame rate, knowing the time of the video and the number of frames in the video.

The get_time_duration function returns the start date and time, as well as the duration of the video file. Please note: if the date and time are missing, the function returns 00:00 on January 1, 1970.

We can also find out the dimensions of the frames and their number using the size function for the image stack.

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

Let's crop the video, leaving only the central part of it.

In [ ]:
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])# Отрисовка первого кадра видео
Out[0]:
No description has been provided for this image

Now, for the first 100 frames of the cropped video, add filtering to create a blur effect.

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

simshow(new_video[:,:,1])# Отрисовка первого кадра видео
Out[0]:
No description has been provided for this image

If we want to save our data in a video, then there is an option to directly save the stack of images in the form of a video file. At the same time, we can independently adjust the encoder parameters and frame rate. The list of available settings is shown in the table below.

In [ ]:
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
Goal encoder_options
Perceptual compression, default is h264. The best solution for most cases (crf=23, preset="medium")
Lossless compression. Fastest, largest file size (crf=0, preset="ultrafast")
Lossless compression. Slowest, minimum file size (crf=0, preset="veryslow")
Direct control of bitrate and frame rate (bit_rate = 400000, gop_size = 10, max_b_frames = 1)
In [ ]:
encoder_options = (crf=23, preset="medium")
VideoIO.save("video.mp4", video, framerate=30, encoder_options=encoder_options)
In [ ]:
 

Conclusion

In this demo, we looked at the possibilities of video processing in Engee and used illustrative examples to make sure that the environment works successfully with video. The technique is the same as for image processing.