Is VideoWriter using compression while saving video? [OpenCV 4]

Hey all,

In advance I will let you know that I not an expert in Computer Vision :frowning: , that’s why there is a chance that my questions might look silly for you and for that I apologize :upside_down_face:

I am doing image acquisition using industrial camera (Nano C 1930) for this purpose I am leveraging their framework or library cvbpy of the camera vendors. Below is the snippet code, through which I acquire frames and save the video using the VideoWriter.

import os
import cvb
import cv2
FPS = 25
CAMERA_WIDTH = 1920
CAMERA_HEIGHT = 1080
CAMERA_VERTICAL_OFFSET = 32
CAMERA_HORIZONTAL_OFFSET = 32
frameSize = (1920, 1080)

def deviceConfiguration(dev_node_map):
    dev_node_map['Std::Width'].value = CAMERA_WIDTH
    dev_node_map['Std::Height'].value = CAMERA_HEIGHT
    # set the Frame rate in Hz
    dev_node_map['Std::AcquisitionFrameRate'].value = FPS
    dev_node_map['Std::OffsetX'].value = CAMERA_HORIZONTAL_OFFSET
    dev_node_map['Std::OffsetY'].value = CAMERA_VERTICAL_OFFSET
    dev_node_map['Cust::autoBrightnessMode'].value = "Active"

if __name__ == '__main__':
    rate_counter = None
    out = cv2.VideoWriter('recording.avi', cv2.VideoWriter_fourcc(*'DIVX'), 25, frameSize)
    with cvb.DeviceFactory.open(cvb.install_path() + "/drivers/GenICam.vin", port=0) as device:
        deviceConfiguration(device.node_maps["Device"])
        device.node_maps["Device"]['Cust::timestampControlLatch'].execute()
        stream = device.stream
        rate_counter = cvb.RateCounter()

        stream.start()
        for i in range(10):
            rate_counter.step()
            image, status = stream.wait()
            if status == cvb.WaitStatus.Ok:
                np_image = cvb.as_array(image, copy=False)
                # save the frames
                out.write(np_image)
                imageRawTimeStamp = "{:.0f}".format(float(image.raw_timestamp))

                print("Acquired image: " + str(i) + " | Timestamp: " + str(imageRawTimeStamp))
                print("Acquired with: " + str(rate_counter.rate) + " fps")

        stream.abort()

output of the above code for acquiring 10 frames is as follows:

Acquired image: 0 | Timestamp: 1612365745947438848
Acquired with: nan fps
Acquired image: 1 | Timestamp: 1612365745987438848
Acquired with: nan fps
Acquired image: 2 | Timestamp: 1612365746027438848
Acquired with: 12.048192771084338 fps
Acquired image: 3 | Timestamp: 1612365746067439104
Acquired with: 13.333333333333334 fps
Acquired image: 4 | Timestamp: 1612365746107439104
Acquired with: 14.285714285714286 fps
Acquired image: 5 | Timestamp: 1612365746147439104
Acquired with: 14.925373134328359 fps
Acquired image: 6 | Timestamp: 1612365746187439104
Acquired with: 15.384615384615385 fps
Acquired image: 7 | Timestamp: 1612365746227439360
Acquired with: 15.873015873015873 fps
Acquired image: 8 | Timestamp: 1612365746267439360
Acquired with: 16.39344262295082 fps
Acquired image: 9 | Timestamp: 1612365746307439360
Acquired with: 16.666666666666668 fps

You can see the output, that FPS is dropped, even I set it to 25, which the camera is capable to give that FPS. Now, If save only images as .bmp or .jpeg format I am getting exactly 25 FPS but, but the problem is that it has storage issue. I have 1 TB SSD even I ran out of the DISK space very quickly for .bmp format and for .jpeg due to compression it is useless. However, for .png format, I am also losing FPS. I know there is bottleneck for example the hard Drive performance that’s why I am using high performance SSD plus other like encoding.

Now my questions are:

  • Is VideoWriter do compression while saving video?

  • What could be other reason while saving that the video FPS is getting dropped?

  • Does the cv2.VideoWrite function is using any kind of compression while saving the video? Because for 10 seconds .bmp format it takes almost 2.25 GB of space, while for video it roughly 12 MB. I am using DIVX codec.

  • If it is using compression, than can anyone nudge me the right direction to use which lossy compression codec for saving the video.

Thanks in advance, any kind of help would be appreciated.

Regards,
Affi

Yes, VideoWriter compresses the video. As a matter of fact, it uses some lower-level libraries to do the compression (ffmpeg).
However compression is a very computationally intensive task, especially if it’s done on the CPU. So you can acquire 25 frames per second, but you can encode only ~15fps. As the acquisition waits for the previous frame to be written, the frame rate drops.
BMP doesn’t use any compression, it just dumps the data on the disk, which is fast. JPG compression is also much faster than DIVX, so it can also keep up with the input flow.
You can try to use a faster codec (MJPG, maybe H264) or use directly some other library that does the video encoding on the GPU.

[Edit] BTW, some details on advanced video encoding (the MPEG-4 type codecs): it tries to eliminate as much redundant data as possible to reduce the file size. As the frames are similar to the previous and next frames, several images images are used to encode/decode the frame. It also tries to guess where are the interesting parts in the movie (what are you watching), and that part is encoded in better quality, the rest in worse quality. So as you can see, there is a lot going on in the encoding.
MJPG creates a video as a series of JPG images, so it should be much faster - but the visual quality is no match for the MPEG-4 techniques. That said, if you save the video for later processing, the perceptual compression of MPEG-4 is as much of an advantage.

1 Like

Hey @kbarni,

Thank you so much for the valuable feedback.

Your feedback was very informative, I have one question, now let suppose, I don’t want any kind of compression, is there an option for the videowriter or the codec that does not perform any compression just like with image for .bmp format, I know for images there is an option, where I can specify values between [1-9] etc…

Regards,
Affi

Here you can find the list of some codecs that don’t do compression: Media Data Atom Types

1 Like