1

I am using python 3.6 and opencv 3.4.1 to capture video from a Logitech C920 webcam. I am used to Windows, where I would write my own DirectShow filters to get access to frames and control the camera. I am finding myself out of my depth on Linux.

I know it can run 24fps at least by using GTK UVC video viewer, but I'm only getting 5fps. I suspect that this is due to the format - to get higher rates I need something like x264. It may be that this is impossible for opencv because it means that it can no longer grab a single frame.

I have tried setting the video codec, but I am told that

cap.set(cv2.CAP_PROP_FORMAT, cv2.VideoWriter_fourcc(...

VIDEOIO ERROR: V4L2: setting property #8 is not supported

Other people have asked similar questions, but I haven't been able to see a convincing answer:

(no answer) Capturing H264 stream with OpenCV

(blames drivers) http://answers.opencv.org/question/30185/frame-capture-is-needlessly-slow/

(sets camera format in c++) OpenCV VideoCapture with H264 CODEC

(also done in c++ and OpenCV 2.4) Capturing 1080p at 30fps from logitech c920 with openCV 2.4.3

I found a link claiming that x264 etc doesn't support frame grabbing, therefore it can't be done, but now I can't find it - this would seem to be contradicted by the answers in c++ and the fact that we can work with x264 file formats.

Any clarity would be appreciated.

EDIT:

As requested, here are the outputs of cv2.getBuildInformation():

General configuration for OpenCV 3.4.1 =====================================
  Version control:               3.4.1

  Platform:
    Timestamp:                   2018-05-19T13:51:11Z
    Host:                        Linux 4.4.0-101-generic x86_64
    CMake:                       3.9.0
    CMake generator:             Unix Makefiles
    CMake build tool:            /usr/bin/gmake
    Configuration:               Release

  CPU/HW features:
    Baseline:                    SSE SSE2 SSE3
      requested:                 SSE3
    Dispatched code generation:  SSE4_1 SSE4_2 FP16 AVX AVX2
      requested:                 SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
      SSE4_1 (3 files):          + SSSE3 SSE4_1
      SSE4_2 (1 files):          + SSSE3 SSE4_1 POPCNT SSE4_2
      FP16 (1 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
      AVX (5 files):             + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
      AVX2 (9 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2

  C/C++:
    Built as dynamic libs?:      NO
    C++ Compiler:                /opt/rh/devtoolset-2/root/usr/bin/c++  (ver 4.8.2)
    C++ flags (Release):         -Wl,-strip-all   -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG
    C++ flags (Debug):           -Wl,-strip-all   -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG
    C Compiler:                  /opt/rh/devtoolset-2/root/usr/bin/cc
    C flags (Release):           -Wl,-strip-all   -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-narrowing -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG
    C flags (Debug):             -Wl,-strip-all   -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-narrowing -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG
    Linker flags (Release):      -L/root/ffmpeg_build/lib
    Linker flags (Debug):        -L/root/ffmpeg_build/lib
    ccache:                      NO
    Precompiled headers:         NO
    Extra dependencies:          /opt/Qt4.8.7/lib/libQtGui.so /opt/Qt4.8.7/lib/libQtTest.so /opt/Qt4.8.7/lib/libQtCore.so /lib64/libz.so /opt/libjpeg-turbo/lib64/libjpeg.a avcodec avformat avutil swscale dl m pthread rt
    3rdparty dependencies:       ittnotify libprotobuf libwebp libpng libtiff libjasper IlmImf

  OpenCV modules:
    To be built:                 calib3d core dnn features2d flann highgui imgcodecs imgproc java_bindings_generator ml objdetect photo python3 python_bindings_generator shape stitching superres video videoio videostab
    Disabled:                    js world
    Disabled by dependency:      -
    Unavailable:                 cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev java python2ts viz
    Applications:                -
    Documentation:               NO
    Non-free algorithms:         NO

  GUI:
    QT:                          YES (ver 4.8.7 EDITION = OpenSource)
      QT OpenGL support:         NO
    GTK+:                        NO
    VTK support:                 NO

  Media I/O:
    ZLib:                        /lib64/libz.so (ver 1.2.3)
    JPEG:                        /opt/libjpeg-turbo/lib64/libjpeg.a (ver )
    WEBP:                        build (ver encoder: 0x020e)
    PNG:                         build (ver 1.6.34)
    TIFF:                        build (ver 42 - 4.0.9)
    JPEG 2000:                   build (ver 1.900.1)
    OpenEXR:                     build (ver 1.7.1)

  Video I/O:
    DC1394:                      NO
    FFMPEG:                      YES
      avcodec:                   YES (ver 58.19.100)
      avformat:                  YES (ver 58.13.100)
      avutil:                    YES (ver 56.18.100)
      swscale:                   YES (ver 5.2.100)
      avresample:                NO
    GStreamer:                   NO
    libv4l/libv4l2:              NO
    v4l/v4l2:                    linux/videodev.h linux/videodev2.h
    gPhoto2:                     NO

  Parallel framework:            pthreads

  Trace:                         YES (with Intel ITT)

  Other third-party libraries:
    Lapack:                      NO
    Eigen:                       NO
    Custom HAL:                  NO
    Protobuf:                    build (3.5.1)

  NVIDIA CUDA:                   NO

  OpenCL:                        YES (no extra features)
    Include path:                /io/opencv/3rdparty/include/opencl/1.2
    Link libraries:              Dynamic load

  Python 3:
    Interpreter:                 /opt/python/cp36-cp36m/bin/python (ver 3.6.5)
    Libraries:                   libpython3.6m.a (ver 3.6.5)
    numpy:                       /opt/python/cp36-cp36m/lib/python3.6/site-packages/numpy/core/include (ver 1.11.3)
    packages path:               lib/python3.6/site-packages

  Python (for build):            /opt/python/cp36-cp36m/bin/python

  Java:
    ant:                         NO
    JNI:                         NO
    Java wrappers:               NO
    Java tests:                  NO

  Matlab:                        NO

  Install to:                    /io/_skbuild/cmake-install
-----------------------------------------------------------------
mike1952
  • 493
  • 5
  • 12
  • Sorry, I probably didn't make it clear enough - I'm only getting 5fps. It's too slow for my needs. That's the problem I'm trying to solve - but from what I can see, the problem is the format. If I'm wrong then please, tell me :) – mike1952 Jul 05 '18 at 09:35
  • 1
    Try using [FFmpeg](https://trac.ffmpeg.org/wiki/Capture/Webcam#Linux) to list pixel formats and encode with different frame rates and supported pixel formats. – zindarod Jul 05 '18 at 09:53
  • I've done as you asked - H.264 is supported. But, as I said, when I try to set the format to H264, I'm told that opencv doesn't support setting camera formats. – mike1952 Jul 05 '18 at 10:03
  • Sorry, now I understand - actually play around in ffmpeg. On it now. – mike1952 Jul 05 '18 at 10:09
  • https://stackoverflow.com/questions/50470593/opencv-3-2-with-python-3-videocapture-changes-settings-of-v4l2 I suspect that this might be part of the problem. Also, ffmpeg has a problem with resetting formats. I hate video :) – mike1952 Jul 05 '18 at 10:23
  • It's not a real answer to the problem, but thanks to your hints I've started streaming vl42 with the correct settings and am opening it as a network stream. There's awful latency, but that's better than the framerate I was getting. I would still prefer to be able to use the system as it is intended though! Thanks for your help so far. You've turned this from something that was ruining my day into something that I'd like to solve - that's a major improvement.# – mike1952 Jul 05 '18 at 10:50
  • Please post the output of `cv2.getBuildInformation()` on [pastebin](https://pastebin.com) and share the link here. – zindarod Jul 05 '18 at 16:47
  • Hi @zindarod, I've posted it. It appears to have been built with v4l2 - I'm not sure exactly what it all means though. – mike1952 Jul 06 '18 at 08:03
  • On my machine it says: `libv4l/libv4l2: NO/YES`. – zindarod Jul 06 '18 at 08:15
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/174490/discussion-between-mike1952-and-zindarod). – mike1952 Jul 06 '18 at 10:03
  • @zindarod if you want credit for the answer, clone mine and I'll mark it as the solution instead of mine. – mike1952 Jul 17 '18 at 10:36

1 Answers1

1

So as zindarod correctly pointed out, the solution is to:

  • run cv2.getBuildInformation()
  • Check if libv4l/libv4l2 has NO/NO as the value (if it doesn't you have some other problem)
  • Compile OpenCV from source.

Compiling OpenCV is tricky, but manageable, even for someone like me who was raised on Windows.

https://docs.opencv.org/3.2.0/d7/d9f/tutorial_linux_install.html https://docs.opencv.org/3.0-beta/doc/tutorials/introduction/linux_eclipse/linux_eclipse.html

Although those are a little out of date. In eclipse you'll need references to opencv_videoio opencv_core opencv_highgui opencv_videoio

#include "opencv2/opencv.hpp"
#include "opencv2/videoio.hpp"
using namespace cv;

int main(int, char**)
{
    VideoCapture cap(0); // open the default camera
    if(!cap.isOpened())  // check if we succeeded
        return -1;

    cap.set(CV_CAP_PROP_FRAME_WIDTH,1920);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT,1080);
    Mat edges;
    namedWindow("camera",1);
    for(;;)
    {
        Mat frame;
        cap >> frame; // get a new frame from camera
        imshow("camera", frame);
        if(waitKey(30) >= 0) break;
    }
    return 0;
}
mike1952
  • 493
  • 5
  • 12