首页 文章

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

提问于
浏览
52

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

15 回答

  • 0

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

  • 17

    我在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);
    

    我用罗技,Trust和飞利浦网络摄像头对它进行了测试

  • 5

    似乎没有解决方案 . 使用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 .

  • 0

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

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

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

  • 0

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

  • 5

    看看这张票:https://code.ros.org/trac/opencv/ticket/376

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

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

    • 重新运行cmake,你会看到“V4L / V4L2:使用libv4l”

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

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

  • 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

    我正在使用debian和ubuntu,我有同样的问题,我无法使用 CV_CAP_PROP_FRAME_WIDTHCV_CAP_PROP_FRAME_HEIGHT 更改视频输入的分辨率

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

  • -1

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

  • 0

    cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH,WIDTH); cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT,HEIGHT); cvQueryFrame(捕捉);

    这不适用于OpenCV 2.2,但如果你使用OpenCV 2.1它将工作正常!

  • -3

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

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

  • 42

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

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

  • 2

    只有一个信息可能对那些难以改变默认捕获分辨率(640 x 480)的人有 Value !我用opencv 2.4.x和一台罗技相机试验了这个问题......并找到了一个解决方法!

    我检测到的行为是默认格式设置为启动摄像头捕获时的初始参数(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这样做!

    希望它会有所帮助 .

    米歇尔BEGEY

  • 4

    试试这个:

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

    应该够了!

相关问题