Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

4K VideoCapture very slow on Windows compared to MS Camera App

Hi!

I have gotten a Logitech BRIO Webcam, which delivers nice smooth 30 fps of 4k images in the native Windows Camera App. Using OpenCV 4.1.0 in Python, this seems impossible. The stream is very slow at the same exposure level. Here is my code:

import cv2
import time

print(cv2.getBuildInformation())

time_sum = 0
frames = 0

capture = cv2.VideoCapture()
capture.open(1 + cv2.CAP_DSHOW)

fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
capture.set(cv2.CAP_PROP_FOURCC, fourcc)
capture.set(cv2.CAP_PROP_FPS, 30)
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 3840)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 2160)

while(1):
    before_timer = time.perf_counter()
    ret, frame = capture.read()
    if frame is None:
        print("Frame is empty")
        break
    else:
        cv2.imshow('VIDEO', frame)
        after_timer = time.perf_counter() - before_timer
        time_sum += after_timer
        frames += 1
        if frames % 30 == 0:
            print("{} per second".format(frames/time_sum))
        cv2.waitKey(1)

Disabling the imshow does not have a significant impact on performance. Using CAP_MSMF as backend will deliver 30 FPS, but the video is just an upscaled version of a lower resolution stream, and sadly useless. I've been looking around the capture backend code for quite a while, but I can't seem to figure out where the problem lies.

When disabling the RGB conversion with capture.set(cv2.CAP_PROP_CONVERT_RGB, 0), the FPS also do not improve.

I also tried the same loop in C++, it was just as slow.

The relevant portion of getBuildInformation() looks like this:

Video I/O:
DC1394:                      NO
FFMPEG:                      YES (prebuilt binaries)
  avcodec:                   YES (58.35.100)
  avformat:                  YES (58.20.100)
  avutil:                    YES (56.22.100)
  swscale:                   YES (5.3.100)
  avresample:                YES (4.0.0)
GStreamer:                   NO
DirectShow:                  YES
Media Foundation:            YES
DXVA:                      NO

Does anyone have any pointers on how to improve video performance? I am at a loss as to what to do. Hardware acceleration might be an option, but I don't know how to get that into my opencv-python package :(

Setting the DEBUG environment variable does not produce any additional logging info.

Thanks a lot for any help!

4K VideoCapture very slow on Windows compared to MS Camera App

Hi!

I have gotten a Logitech BRIO Webcam, which delivers nice smooth 30 fps of 4k images in the native Windows Camera App. Using OpenCV 4.1.0 in Python, this seems impossible. The stream is very slow at the same exposure level. Here is my code:

import cv2
import time

print(cv2.getBuildInformation())

time_sum = 0
frames = 0

capture = cv2.VideoCapture()
capture.open(1 + cv2.CAP_DSHOW)

fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
capture.set(cv2.CAP_PROP_FOURCC, fourcc)
capture.set(cv2.CAP_PROP_FPS, 30)
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 3840)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 2160)

while(1):
    before_timer = time.perf_counter()
    ret, frame = capture.read()
    if frame is None:
        print("Frame is empty")
        break
    else:
        cv2.imshow('VIDEO', frame)
        after_timer = time.perf_counter() - before_timer
        time_sum += after_timer
        frames += 1
        if frames % 30 == 0:
            print("{} per second".format(frames/time_sum))
        cv2.waitKey(1)

Disabling the imshow does not have a significant impact on performance. Using CAP_MSMF as backend will deliver 30 FPS, but the video is just an upscaled version of a lower resolution stream, and sadly useless. I've been looking around the capture backend code for quite a while, but I can't seem to figure out where the problem lies.

When disabling the RGB conversion with capture.set(cv2.CAP_PROP_CONVERT_RGB, 0), the FPS also do not improve.

I also tried the same loop in C++, it was just as slow.

The relevant portion of getBuildInformation() looks like this:

Video I/O:
DC1394:                      NO
FFMPEG:                      YES (prebuilt binaries)
  avcodec:                   YES (58.35.100)
  avformat:                  YES (58.20.100)
  avutil:                    YES (56.22.100)
  swscale:                   YES (5.3.100)
  avresample:                YES (4.0.0)
GStreamer:                   NO
DirectShow:                  YES
Media Foundation:            YES
DXVA:                      NO

Does anyone have any pointers on how to improve video performance? I am at a loss as to what to do. Hardware acceleration might be an option, but I don't know how to get that into my opencv-python package :(

Setting the DEBUG environment variable does not produce any additional logging info.

Thanks a lot for any help!

Edit: C++-Code.

#include "stdafx.h"
#include "opencv2\opencv.hpp"
int main()
{
    cv::VideoCapture capture;

    capture.open(1 + cv::CAP_DSHOW);

    if (!capture.isOpened()) {
        std::cerr << "Error opening video stream" << std::endl;
        return -1;
    }

    capture.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));
    capture.set(cv::CAP_PROP_FPS, 30);
    capture.set(cv::CAP_PROP_FRAME_WIDTH, 3840);
    capture.set(cv::CAP_PROP_FRAME_HEIGHT, 2160);

    while (true) {
        cv::Mat frame;
        capture >> frame;

        if (frame.empty()) {
            break;
            std::cerr << "Frame is empty." << std::endl;
        }
        cv::imshow("Brio", frame);

        char c = (char)cv::waitKey(1);

        if (c == 27) {
            break;
        }
    }

    capture.release();
    cv::destroyAllWindows();

    return 0;
}

Using chrono-STL-functions to measure the time unforntunately lead to an internal compiler error. But I can judge from the display that the result is the same.