views:

11320

answers:

10

In my C/C++ program, I'm using OpenCV to capture images from my webcam. The camera (Logitech QuickCam IM) can capture at resolutions 320x240, 640x480 and 1280x960. But, for some strange reason, OpenCV gives me images of resolution 320x240 only. Calls to change the resolution using cvSetCaptureProperty() with other resolution values just don't work. How do I capture images with the other resolutions possible with my webcam?

+6  A: 

There doesn't seem to be a solution. The resolution can be increased to 640x480 using this hack shared by lifebelt77. Here are the details reproduced:

Add to highgui.h:

#define CV_CAP_PROP_DIALOG_DISPLAY 8
#define CV_CAP_PROP_DIALOG_FORMAT 9
#define CV_CAP_PROP_DIALOG_SOURCE 10
#define CV_CAP_PROP_DIALOG_COMPRESSION 11
#define CV_CAP_PROP_FRAME_WIDTH_HEIGHT 12

Add the function icvSetPropertyCAM_VFW to cvcap.cpp:

static int icvSetPropertyCAM_VFW( CvCaptureCAM_VFW* capture, int property_id, double value )
{
    int result = -1;
    CAPSTATUS capstat;
    CAPTUREPARMS capparam;
    BITMAPINFO btmp;

    switch( property_id )
    {
        case CV_CAP_PROP_DIALOG_DISPLAY:
            result = capDlgVideoDisplay(capture->capWnd);
            //SendMessage(capture->capWnd,WM_CAP_DLG_VIDEODISPLAY,0,0);
            break;

        case CV_CAP_PROP_DIALOG_FORMAT:
            result = capDlgVideoFormat(capture->capWnd);
            //SendMessage(capture->capWnd,WM_CAP_DLG_VIDEOFORMAT,0,0);
            break;

        case CV_CAP_PROP_DIALOG_SOURCE:
            result = capDlgVideoSource(capture->capWnd);
            //SendMessage(capture->capWnd,WM_CAP_DLG_VIDEOSOURCE,0,0);
            break;

        case CV_CAP_PROP_DIALOG_COMPRESSION:
            result = capDlgVideoCompression(capture->capWnd);
            break;

        case CV_CAP_PROP_FRAME_WIDTH_HEIGHT:
            capGetVideoFormat(capture->capWnd, &btmp, sizeof(BITMAPINFO));
            btmp.bmiHeader.biWidth = floor(value/1000);
            btmp.bmiHeader.biHeight = value-floor(value/1000)*1000;
            btmp.bmiHeader.biSizeImage = btmp.bmiHeader.biHeight *
            btmp.bmiHeader.biWidth * btmp.bmiHeader.biPlanes *
            btmp.bmiHeader.biBitCount / 8;
            capSetVideoFormat(capture->capWnd, &btmp, sizeof(BITMAPINFO));
            break;

        default:
            break;
    }

    return result;
}

and edit captureCAMVFWvtable as following:

static CvCaptureVTable captureCAM_VFW_vtable =
{
6,
(CvCaptureCloseFunc)icvCloseCAM_VFW,
(CvCaptureGrabFrameFunc)icvGrabFrameCAM_VFW,
(CvCaptureRetrieveFrameFunc)icvRetrieveFrameCAM_VFW,
(CvCaptureGetPropertyFunc)icvGetPropertyCAM_VFW,
(CvCaptureSetPropertyFunc)icvSetPropertyCAM_VFW, // was NULL
(CvCaptureGetDescriptionFunc)0
};

Now rebuilt highgui.dll.

Ashwin
+3  A: 

I've done image processing in linux before and skipped OpenCV's built in camera functionality because it's (as you've discovered) incomplete.

Depending on your OS you may have more luck going straight to the hardware through normal channels as opposed to through openCV. If you are using Linux, video4linux or video4linux2 should give you relatively trivial access to USB webcams and you can use libavc1394 for firewire. Depending on the device and the quality of the example code you follow, you should be able to get the device running with the parameters you want in an hour or two.

Edited to add: You are on your own if its Windows. I imagine it's not much more difficult but I've never done it.

lbrandy
+3  A: 

I strongly suggest using VideoInput lib, it supports any DirectShow device (even multiple devices at the same time) and is more configurable. You'll spend five minutes make it play with OpenCV.

martjno
+8  A: 

I'm using openCV 1.1pre1 under Windows (videoinput library is used by default by this version of openCv under windows).

With these instructions I can set camera resolution. Note that I call the old cvCreateCameraCapture instead of cvCaptureFromCam.

capture = cvCreateCameraCapture(cameraIndex);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );

videoFrame = cvQueryFrame(capture);

I've tested it with Logitech, Trust and Philips webcams

Grifo
Works for me too on OpenCV 1.1, and I'd recommend this to be the accepted answer.
Ray Hidayat
yep, I confirm this works for me too. The current accepted solution is not necessary.
Plumo
The docs say this isn't supported, but it even works at HD resolutions. However, if the requested resolution is not available from the camera, it falls back a default resolution silently. The current accepted solution is not necessary.
Nestor
check the return values from cvSetCapture Property not all cameras will accept the instruction
Martin Beckett
A: 

I tried this solution too. But I have problemes with it. I can't find captureCAMVFWvtable in cvcap.cpp. I'm using openCV1pre1.1 too.

Can anyone help me please?

Melle
A: 

I have a similar problem.

I have to create a .AVI video, using OpenCV, and the video must have the resolution of 2048x1560. But what comes out is an empty .AVI file, with 0Kb

the biggest resolution that I got to work is 640x540, but there are smaller resolutions that dont work either (e.g. 540x542 works, but 542x540 doesnt work), so i dont really see a pattern as to which resolutions work and wich dont.

im using cvCreateVideoWriter( ) with MPEG-4 codec (DIVX) to create the video, I have klite_mega_codec_pack installed in my PC, and im using cvResize( ) to resize the frames into the new resolution.

Can anybody help me with that?

HTC55
A: 

I too have problems with opencv, yet mine is not the resolution, im happy with 640 x 480, but its very slooooow at around under 10fps for capturing images using capture = cvCaptureFromCAM( 0 );

and then repeatedly calling: frame = cvQueryFrame( capture); //capture webcam image as fast as possible.

I will try to use VideoInput lib as mentioned by someone else, but I have not heard about them at all....usually its opencv + directshow.

Stuart
A: 

cvQueryFrame(capture);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, any_supported_size );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, any_supported_size);

cvQueryFrame(capture);

should be just enough!

mg72
A: 

Try this:

capture = cvCreateCameraCapture(-1);
//set resolution
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, frameWidth);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, frameHeight);
fantom1210
A: 

Check this ticket out: https://code.ros.org/trac/opencv/ticket/376

"The solution is to use the newer libv4l-based wrapper.

  1. install libv4l-dev (this is how it's called in Ubuntu)

  2. rerun cmake, you will see "V4L/V4L2: Using libv4l"

  3. rerun make. now the resolution can be changed. tested with built-in isight on MBP."

This fixed it for me using Ubuntu and might aswell work for you.

Yo-L