在OpenCV中提高相机捕获分辨率

时间:2020-03-05 18:40:16  来源:igfitidea点击:

在我的C / C ++程序中,我正在使用OpenCV从网络摄像头捕获图像。摄像机(Logitech QuickCam IM)可以以320x240、640x480和1280x960的分辨率捕获。但是,出于某些奇怪的原因,OpenCV仅给我提供了分辨率为320x240的图像。使用cvSetCaptureProperty()和其他分辨率值来更改分辨率的调用不起作用。如何使用网络摄像头以其他分辨率捕获图像?

解决方案

回答

似乎没有解决办法。使用lifebelt77共享的此技巧,可以将分辨率提高到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。

回答

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

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

编辑添加:如果我们使用的是Windows,则自己运行。我想这并不困难,但我从未做到过。

回答

我强烈建议使用VideoInput lib,它支持任何DirectShow设备(甚至可以同时使用多个设备),并且更具可配置性。我们将花费五分钟使其与OpenCV一起播放。

回答

我在Windows下使用openCV 1.1pre1(默认情况下,此版本的openCv在Windows下使用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);

我已经使用Logitech,Trust和Philips网络摄像头对其进行了测试

回答

cvQueryFrame(capture);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, any_supported_size );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, any_supported_size);

cvQueryFrame(capture);

应该足够了!

回答

试试这个:

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

回答

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

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

  • 安装libv4l-dev(这是在Ubuntu中的称呼方式)
  • 重新运行cmake,我们将看到" V4L / V4L2:使用libv4l"
  • 重新运行。现在可以更改分辨率。在MBP上使用内置isight进行了测试。"

这可以使用Ubuntu为我修复,也可以为我们工作。

回答

我发现在Windows(从Win98到WinXP SP3)中,OpenCV经常使用Microsoft的VFW库来进行摄像机访问。问题在于它通常非常慢(例如最多捕获15 FPS帧)和越野车(因此cvSetCaptureProperty为什么通常不起作用)。幸运的是,我们通常可以在其他软件(特别是" AMCAP",这是一个易于使用的演示程序)中更改分辨率,这将影响OpenCV将使用的分辨率。例如,我们可以运行AMCAP来将分辨率设置为640x480,然后OpenCV从那时起将默认使用该分辨率!

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