OpenCV: can't set resolution of video capture
Asked Answered
M

4

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/

Macknair answered 6/5, 2013 at 1:19 Comment(5)
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.Spearmint
Posted! The problem is exhibited with simply a modified version of OpenCV's VideoCapture example.Macknair
I've tried it now with a C920 and it produced exactly the same result.Macknair
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.Spearmint
@Tae-SungShin, I suspect the reason things worked for you is that you used the libv4l version of OpenCV, see my answer.Regain
R
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.)

Regain answered 20/4, 2016 at 22:37 Comment(14)
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.Regain
How did you get python bindings to work with opencv3.1?Limpet
@user592419, I did not do anything special in the build (used this cmake). I usually skip make install and do sudo cp lib/cv2.so /usr/local/lib/python2.7/dist-packages/ directly.Regain
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.Limpet
@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...Regain
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?Limpet
I just added it to /usr/local/lib/python2.7/site-packages and then set PYTHONPATH to be that and stilll no cigar.Limpet
sudo make install?Regain
i ran that earlier before cp'ing the cv2.so.Limpet
@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.Recollect
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.Regain
@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.Recollect
@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...Regain
Thanks, tons of good advice in this post. The WITH_LIBV4L did the trick, here is my make options when building for java:Dragonnade
D
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 ..

Dragonnade answered 10/4, 2017 at 3:21 Comment(0)
A
-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

Ament answered 19/8, 2015 at 21:3 Comment(1)
This will change the resolution of captured video recorded by v4l2-ctl and has no effect on your c++ program.Recollect
G
-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.

Gorged answered 4/9, 2014 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.