Engee documentation
Notebook

Video processing

In this demonstration, let's see what can be done with video using Engee. To do this, we will work with a video clip taken from the Internet. The video is shown 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 transformations of the vector 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 by knowing the video time 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. Note: if the date and time are missing, the function will return 00:00 1 January 1970.

We can also find out frame sizes and frame counts 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 centre 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 add filtering to the first 100 frames of the cropped video 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, there is an option to directly save the image stack in the form of a video file. In this case, we can independently adjust the encoder parameters and frame rate. The list of available settings is presented 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

| target | encoder_options | | ----------- | ----------- | | Perceptual compression, default h264. Best solution for most cases | (crf=23, preset="medium") | | Lossless compression. Fastest, largest file size | (crf=0, preset="ultrafast") | | Lossless compression. Slowest, smallest file size | (crf=0, preset="veryslow") | | | Direct control of bitrate and rate within frames | (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 demonstration, we have looked at the video processing capabilities of Engee and have seen how the environment successfully handles video. The methodology is the same as for image processing.