提高OpenCV中的摄像头捕获分辨率

时间:2008-08-18 07:45:33

标签: c image opencv webcam resolutions

在我的C / C ++程序中,我正在使用OpenCV从我的网络摄像头捕获图像。相机(Logitech QuickCam IM)可以以 320x240 640x480 1280x960 的分辨率进行拍摄。但是,由于一些奇怪的原因,OpenCV只给我分辨率 320x240 的图像。使用 cvSetCaptureProperty()和其他分辨率值调用更改分辨率的调用不起作用。如何使用我的网络摄像头以其他可能的分辨率捕获图像?

15 个答案:

答案 0 :(得分:42)

我在Windows下使用openCV 1.1pre1(Windows下这个版本的openCv默认使用videoinput库。)

根据这些说明,我可以设置相机分辨率。请注意,我调用旧的cvCreateCameraCapture而不是cvCaptureFromCam。

capture = cvCreateCameraCapture(cameraIndex);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );


videoFrame = cvQueryFrame(capture);

我使用罗技,信任和飞利浦网络摄像头进行了测试

答案 1 :(得分:17)

似乎没有解决方案。使用 lifebelt77 共享的this hack,分辨率可以增加到 640x480 。以下是转载的细节:

添加到 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

icvSetPropertyCAM_VFW 功能添加到 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;
}

并编辑 captureCAM_VFW_vtable ,如下所示:

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
};

现在重建 highgui.dll

答案 2 :(得分:5)

我强烈建议使用VideoInput lib,它支持任何DirectShow设备(甚至同时支持多个设备),并且更易于配置。你花了五分钟玩OpenCV。

答案 3 :(得分:5)

我之前在linux中完成了图像处理,并跳过了OpenCV的内置摄像头功能,因为它(正如你所发现的那样)不完整。

根据您的操作系统,您可以通过正常渠道直接进入硬件,而不是通过openCV。如果您使用的是Linux,那么video4linux或video4linux2应该可以让您轻松访问USB网络摄像头,并且可以使用libavc1394进行火线。根据设备和您遵循的示例代码的质量,您应该能够在一两个小时内使用所需的参数运行设备。

编辑添加:如果是Windows,你就是自己的。我想这并不困难,但我从来没有这样做过。

答案 4 :(得分:5)

代码我终于在Python中工作了一次Aaron Haun指出我需要在使用之前定义set函数的参数。

#Camera_Get_Set.py
#By Forrest L. Erickson of VRX Company Inc. 8-31-12.
#Opens the camera and reads and reports the settings.
#Then tries to set for higher resolution.
#Workes with Logitech C525 for resolutions 960 by 720 and 1600 by 896


import cv2.cv as cv
import numpy

CV_CAP_PROP_POS_MSEC = 0
CV_CAP_PROP_POS_FRAMES = 1
CV_CAP_PROP_POS_AVI_RATIO = 2
CV_CAP_PROP_FRAME_WIDTH = 3
CV_CAP_PROP_FRAME_HEIGHT = 4
CV_CAP_PROP_FPS = 5
CV_CAP_PROP_POS_FOURCC = 6
CV_CAP_PROP_POS_FRAME_COUNT = 7
CV_CAP_PROP_BRIGHTNESS = 8
CV_CAP_PROP_CONTRAST = 9
CV_CAP_PROP_SATURATION = 10
CV_CAP_PROP_HUE = 11

CV_CAPTURE_PROPERTIES = tuple({
CV_CAP_PROP_POS_MSEC,
CV_CAP_PROP_POS_FRAMES,
CV_CAP_PROP_POS_AVI_RATIO,
CV_CAP_PROP_FRAME_WIDTH,
CV_CAP_PROP_FRAME_HEIGHT,
CV_CAP_PROP_FPS,
CV_CAP_PROP_POS_FOURCC,
CV_CAP_PROP_POS_FRAME_COUNT,
CV_CAP_PROP_BRIGHTNESS,
CV_CAP_PROP_CONTRAST,
CV_CAP_PROP_SATURATION,
CV_CAP_PROP_HUE})

CV_CAPTURE_PROPERTIES_NAMES = [
"CV_CAP_PROP_POS_MSEC",
"CV_CAP_PROP_POS_FRAMES",
"CV_CAP_PROP_POS_AVI_RATIO",
"CV_CAP_PROP_FRAME_WIDTH",
"CV_CAP_PROP_FRAME_HEIGHT",
"CV_CAP_PROP_FPS",
"CV_CAP_PROP_POS_FOURCC",
"CV_CAP_PROP_POS_FRAME_COUNT",
"CV_CAP_PROP_BRIGHTNESS",
"CV_CAP_PROP_CONTRAST",
"CV_CAP_PROP_SATURATION",
"CV_CAP_PROP_HUE"]


capture = cv.CaptureFromCAM(0)

print ("\nCamera properties before query of frame.")
for i in range(len(CV_CAPTURE_PROPERTIES_NAMES)):
#    camera_valeus =[CV_CAPTURE_PROPERTIES_NAMES, foo]
    foo = cv.GetCaptureProperty(capture, CV_CAPTURE_PROPERTIES[i])
    camera_values =[CV_CAPTURE_PROPERTIES_NAMES[i], foo]
#    print str(camera_values)
    print str(CV_CAPTURE_PROPERTIES_NAMES[i]) + ": " + str(foo)


print ("\nOpen a window for display of image")
cv.NamedWindow("Camera", 1)
while True:
    img = cv.QueryFrame(capture)
    cv.ShowImage("Camera", img)
    if cv.WaitKey(10) == 27:
        break
cv.DestroyWindow("Camera")


#cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 1024)
#cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 768)
cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 1600)
cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 896)


print ("\nCamera properties after query and display of frame.")
for i in range(len(CV_CAPTURE_PROPERTIES_NAMES)):
#    camera_valeus =[CV_CAPTURE_PROPERTIES_NAMES, foo]
    foo = cv.GetCaptureProperty(capture, CV_CAPTURE_PROPERTIES[i])
    camera_values =[CV_CAPTURE_PROPERTIES_NAMES[i], foo]
#    print str(camera_values)
    print str(CV_CAPTURE_PROPERTIES_NAMES[i]) + ": " + str(foo)


print ("/nOpen a window for display of image")
cv.NamedWindow("Camera", 1)
while True:
    img = cv.QueryFrame(capture)
    cv.ShowImage("Camera", img)
    if cv.WaitKey(10) == 27:
        break
cv.DestroyWindow("Camera")

答案 5 :(得分:5)

检查此票证: https://code.ros.org/trac/opencv/ticket/376

“解决方案是使用较新的基于libv4l的包装器。

  1. 安装libv4l-dev(这是在Ubuntu中调用的方式)

  2. 重新运行cmake,您将看到“V4L / V4L2:使用libv4l”

  3. 重新运行make。现在分辨率可以改变。在MBP上进行了内置测试。“

  4. 这使用Ubuntu为我修复了它,并且可能也适合你。

答案 6 :(得分:4)

我正在使用debian和ubuntu,我有同样的问题,我无法使用 CV_CAP_PROP_FRAME_WIDTH CV_CAP_PROP_FRAME_HEIGHT

更改视频输入的分辨率

我发现原因是缺少图书馆。 我通过synaptic,重建 OpenCV安装了 lib4l-dev ,问题解决了!

答案 7 :(得分:2)

我发布此内容是为了确保没有其他人在此setproperty函数上浪费时间。我花了两天的时间才看到似乎没有任何效果。所以我挖出了代码(我第一次安装了库)。这就是实际发生的事情--cvSetCaptureProperty,在CvCapture类中调用setProperty,看看setProperty什么都不做。它只是返回false。 相反,我将使用另一个库来为OpenCV提供捕获视频/图像。我正在使用OpenCV 2.2

答案 8 :(得分:0)

我发现在Windows中(从Win98到WinXP SP3),OpenCV经常会使用微软的VFW库进行摄像头访问。这个问题是它通常很慢(比如最多15 FPS帧捕获)和bug(因此cvSetCaptureProperty通常不起作用)。幸运的是,您通常可以更改其他软件的分辨率(特别是“AMCAP”,这是一个容易获得的演示程序),它将影响OpenCV将使用的分辨率。例如,您可以运行AMCAP将分辨率设置为640x480,然后OpenCV默认会从该点开始使用它!

但是如果你可以使用不同的Windows摄像头访问库,例如使用非常高效的DirectShow(DirectX的一部分)访问摄像头的“videoInput”库http://muonics.net/school/spring05/videoInput/。或者,如果你有一个专业品质的相机,那么它通常会带有一个自定义API,让你可以访问相机,你可以使用它来快速访问,并能够改变分辨率和许多其他东西。

答案 9 :(得分:0)

  

cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH,WIDTH);

     

cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT,HEIGHT);

     

cvQueryFrame(捕捉);

这对OpenCV 2.2不起作用,但是如果你使用OpenCV 2.1它会正常工作!

答案 10 :(得分:0)

在Windows下尝试使用VideoInput库: http://robocraft.ru/blog/computervision/420.html

答案 11 :(得分:0)

对于难以更改默认捕获分辨率(640 x 480)的人来说,只有一个信息可能很有价值!我用opencv 2.4.x和一台Logitech相机试验了一个这样的问题...并找到了一个解决方法!

我检测到的行为是默认格式设置为启动摄像头捕获时的初始参数(cvCreateCameraCapture),以及所有更改高度或宽度的请求:

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, ... 

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, ...
之后

是不可能的!实际上,我发现添加了ioctl函数的返回错误,V4l2驱动程序正在为这些请求返回 EBUSY ! 因此,一种解决方法应该是直接在highgui / cap_v4l.cpp中更改默认值:

*#define DEFAULT_V4L_WIDTH  1280    // Originally 640* 

*#define DEFAULT_V4L_HEIGHT 720     // Originally 480*

之后,我刚刚重新编译 opencv ...并且没有任何问题就赶到了1280 x 720!当然,更好的解决办法应该是停止采集,更改参数,然后重新启动流,但是我不熟悉opencv这样做!

希望它会有所帮助。

Michel BEGEY

答案 12 :(得分:0)

如果您使用的是Windows平台,请尝试使用DirectShow(IAMStreamConfig)。

http://msdn.microsoft.com/en-us/library/dd319784%28v=vs.85%29.aspx

答案 13 :(得分:-1)

试试这个:

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

答案 14 :(得分:-3)

cvQueryFrame(capture);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, any_supported_size );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, any_supported_size);

cvQueryFrame(capture);

应该够了!