12

I am using OpenCV 2.4.5 on Ubuntu 12.04 64-bit. I would like to be able to set the resolution of the input from my Logitech C310 webcam. The camera supports up to 1280x960 at 30fps, and I am able to view the video at this resolution in guvcview. But OpenCV always gets the video at only 640x480.

Trying to change the resolution with cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280) and cap.set(CV_CAP_PROP_FRAME_HEIGHT, 960) immediately after the VideoCapture cap is created has no effect; trying to set them immediately before getting every frame causes the program to crash immediately. I cannot reduce the resolution with this method either. I am also getting the error "HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP". I think this may be related, because it appears once when the VideoCapture is created, and once when I try to set the width and height (but, oddly, not if I try to set only one of them).

I know I'm not the first to have this problem, but I have yet to find a solution after much Googling and scouring of SO and elsewhere on the internet (among the many things I've already tried to no avail is the answer to this StackOverflow question: Increasing camera capture resolution in OpenCV). Is this a bug in OpenCV? If so, it's a rather glaring one.

Here's an example of code that exhibits the problem (just a modified version of OpenCV's video display code):

#include <cv.h>
#include <highgui.h>
using namespace cv;

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

    cap.set(CV_CAP_PROP_FRAME_WIDTH, 160);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 120);

    Mat image;
    namedWindow("Video", CV_WINDOW_AUTOSIZE);

    while(1)
    {
            // cap.set(CV_CAP_PROP_FRAME_WIDTH, 160);
            // cap.set(CV_CAP_PROP_FRAME_HEIGHT, 120);
            cap >> image;

            imshow("Video", image);

            if(waitKey(10) == 99 ) break;
    }
    return 
}

As it is, that gets me two "HIGHGUI ERROR"s as described above and I get a 640x480 output. I know that 160x120 is a resolution that my camera supports from running v4l2-ctl --list-formats-ext. If I uncomment the two commented-out lines in the while loop, the program crashes immediately.

These might be related or have possible solutions: http://answers.opencv.org/question/11427/decreasing-capture-resolution-of-webcam/, http://answers.opencv.org/question/30062/error-setting-resolution-of-video-capture-device/

Community
  • 1
  • 1
erobertc
  • 644
  • 1
  • 9
  • 20
  • Please post your code. If something does not work, it must be most likely your code so we can't help you without your code. I haven't used C310 but I didn't have any problem with setting resolution with C920. – Tae-Sung Shin May 06 '13 at 03:12
  • Posted! The problem is exhibited with simply a modified version of OpenCV's VideoCapture example. – erobertc May 06 '13 at 19:41
  • I've tried it now with a C920 and it produced exactly the same result. – erobertc May 07 '13 at 00:06
  • 1
    You are getting "highgui error." That may mean you don't have any problem with setting up image size but your code can't handle the speed of image grabbing. Your code has delay accumulating after getting the image. I suspect that is cause of the error. Usually, you should have a separate thread for grabbing and another thread for displaying the images gotten. Your code does not have either. I just tried my code and didn't have any problem with setting up that resolution. – Tae-Sung Shin May 07 '13 at 00:37
  • @Tae-SungShin, I suspect the reason things worked for you is that you used the libv4l version of OpenCV, see my [answer](http://stackoverflow.com/a/36756451/1628638). – Ulrich Stern Apr 28 '16 at 16:40

4 Answers4

5

This is a bug in the v4l "version" (build) of OpenCV 2.4 (including 2.4.12), but the bug is not in the libv4l version. For OpenCV 3.1.0, neither the v4l nor the libv4l version has the bug.

(Your error error message HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP indicates that you have the v4l version; the message is in cap_v4l.cpp, see code, but not in cap_libv4l.cpp.)

A workaround to get the v4l version of OpenCV 2.4 to work at a fixed resolution other than 640x480 is changing the values for DEFAULT_V4L_WIDTH and DEFAULT_V4L_HEIGHT in modules/highgui/src/cap_v4l.cpp and re-building OpenCV, kudos to this answer.

If you want to build the libv4l version instead, all you likely need to do is install libv4l-dev and rebuild OpenCV; WITH_LIBV4L was enabled by default for me. If it is not, your cmake command should contain

-D WITH_LIBV4L=ON

The cmake output (or version_string.tmp) for a libv4l build contains something like

  Video I/O:
    ...
    V4L/V4L2:   Using libv4l1 (ver 0.8.6) / libv4l2 (ver 0.8.6)

(For a v4l build, it is just V4L/V4L2: NO/YES.)

Community
  • 1
  • 1
Ulrich Stern
  • 10,761
  • 5
  • 55
  • 76
  • PS: the bug is also in OpenCV 3.0.0. For the *workaround*, the file to change has moved to modules/videoio/src/cap_v4l.cpp. – Ulrich Stern Apr 28 '16 at 16:33
  • How did you get python bindings to work with opencv3.1? – user592419 May 12 '16 at 17:33
  • @user592419, I did not do anything special in the build (used [this](http://stackoverflow.com/a/29238291/1628638) `cmake`). I usually skip `make install` and do `sudo cp lib/cv2.so /usr/local/lib/python2.7/dist-packages/` directly. – Ulrich Stern May 12 '16 at 18:47
  • I don't seem to have lib/cv2.so. I have a whole lot of lib/libopencv_*.so files and I have a lib/python3/cv2.cpython-34m.so file, but not the one you specify. – user592419 May 12 '16 at 19:01
  • @user592419, I have the lib/libopencv_*.so but **no** lib/python3 folder. So my guess is something went wrong for the Python 3 part in your case... – Ulrich Stern May 12 '16 at 19:25
  • I rebuilt and the cv2.so is there now, but CPing it to that directory didn't work. Similarly with /usr/lib/python2.7/dist-packages/. Thoughts on where it should go? – user592419 May 12 '16 at 21:44
  • I just added it to /usr/local/lib/python2.7/site-packages and then set PYTHONPATH to be that and stilll no cigar. – user592419 May 12 '16 at 21:47
  • `sudo make install`? – Ulrich Stern May 12 '16 at 21:56
  • i ran that earlier before cp'ing the cv2.so. – user592419 May 12 '16 at 23:28
  • @Ulrich Stern, I've done the rebuild with `-D WITH_LIBV4L=ON` parameter and then `make` and `install` but no change, already get `HIGHGUI ERROR` and resolution didn't changed. – SAMPro Jul 17 '16 at 04:31
  • I just added the cmake output for a libv4l build to my answer above. If you got the output for v4l, I assume `libv4l-dev` was not installed in your case. – Ulrich Stern Jul 17 '16 at 15:13
  • @Ulrich Stern, I take a look at `cmake` output and got something like yours (but ver 1.11.0), but sadly can't change resolution in the c++. I also can change the resolution and save still image using v4l2-ctl. – SAMPro Jul 21 '16 at 09:43
  • @SAMPro, if you have not done it yet, you could try the v4l version of OpenCV 3.1. If this does not help, looking into the OpenCV source code may be your best bet... – Ulrich Stern Jul 25 '16 at 16:20
  • Thanks, tons of good advice in this post. The WITH_LIBV4L did the trick, here is my make options when building for java: – Austin Apr 10 '17 at 03:18
0

Just wanted to add my CMAKE options to build with Java on the Raspberry Pi 3 based on Ulrich's comprehensive answer for OpenCV 3.2.0. Make a /build folder a in the same folder as OpenCV CMakeList.txt and execute this script for the new /build folder:

sudo cmake -D CMAKE_BUILD_TYPE=RELEASE -D WITH_OPENCL=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_SHARED_LIBS=OFF -D JAVA_INCLUDE_PATH=$JAVA_HOME/include -D JAVA_AWT_LIBRARY=$JAVA_HOME/jre/lib/arm/libawt.so -D JAVA_JVM_LIBRARY=$JAVA_HOME/jre/lib/arm/server/libjvm.so -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_TESTS=OFF -D WITH_MATLAB=OFF -D WITH_CUFFT=OFF -D WITH_CUDA=OFF -D WITH_CUBLAS=OFF -D WITH_GTK=OFF -D WITH_WEBP=OFF -D BUILD_opencv_apps=OFF -D BUILD_PACKAGE=OFF -D WITH_LIBV4L=ON ..

Austin
  • 1,018
  • 9
  • 20
-1

You can use v4l2-ctl to set frame size of captured video like below.

v4l2-ctl --set-fmt-video=width=1920,height=1080,pixelformat=1

You can find more information at this link

mpromonet
  • 11,326
  • 43
  • 62
  • 91
Ömer Taban
  • 130
  • 1
  • 5
  • This will change the resolution of captured video recorded by `v4l2-ctl` and has no effect on your c++ program. – SAMPro Jul 23 '16 at 07:05
-2

Maybe you can try this, but I am not sure if this is what you want:

#include <X11/Xlib.h>

Display* disp = XOpenDisplay(NULL);
Screen*  scrn = DefaultScreenOfDisplay(disp);
int height = scrn->height;
int width  = scrn->width;

//Create window for the ip cam video
cv::namedWindow("Front", CV_WINDOW_NORMAL);

cvSetWindowProperty( "Front", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN );

//Position of the screen where the video is shows
cvMoveWindow("Front", 0, 0);
cvResizeWindow( "Front", width, height );

Like this you get the full screen for any screen.

mpromonet
  • 11,326
  • 43
  • 62
  • 91
user3766585
  • 91
  • 1
  • 3
  • 10