使用OpenCV 2.4.3从Logitech c920捕获1080p 30fps的视频

24

我正在尝试在OpenCV中捕获我的Logitech C920视频流。使用Labview,我可以以30fps 1080p的速度访问MJPG流。在opencv中,我只能使用5fps或640x480。

这是与相机设置相关的代码:

this->camRef.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
this->camRef.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
this->camRef.set(CV_CAP_PROP_FOURCC,CV_FOURCC('M','J','P','G'));

这些都返回1,但我得到了一条1080p的5fps流,对应于YUY2流。
如果我添加以下行:

this->camRef.set(CV_CAP_PROP_FPS, 30);

这将返回0。

我得到了一个640x480的30帧每秒的流。对我来说,看起来 MJPG 设置没有被接受,但我不知道该怎么做或如何解决。

编辑:以下操作会导致程序崩溃。

 this->camRef.read(this->image);
 std::cout<< this->camRef.get(CV_CAP_PROP_FOURCC)                            << std::endl;
 std::cout<< this->camRef.set(CV_CAP_PROP_FRAME_WIDTH, config.width)         << std::endl;
 std::cout<< this->camRef.set(CV_CAP_PROP_FRAME_HEIGHT, config.height)       << std::endl;
 std::cout<< this->camRef.set(CV_CAP_PROP_FOURCC,CV_FOURCC('M','J','P','G')) << std::endl;
 std::cout<< this->camRef.get(CV_CAP_PROP_FOURCC)                            << std::endl;

然后在我的运行代码中,我有以下内容:

void camera::run()
{
    while(true)
    {
        if(this->camRef.read(this->image) == 0)
        {
           if(this->capture)
            {
                cv::imwrite(fileName,this->image);
                this->count++;
            }
        }
        msleep(15);
    }
}

编辑2:解决方法是在设置相机高度和宽度之前设置fourCC编解码器。


如果您想设置fps(必须由相机支持),则必须在编解码器设置之后但在宽度/高度设置之前进行。 - MartinM
1
听起来你的EDIT2给了你1080p 30fps。应该将其转化为答案并接受,以使问题看起来已解决。 - Ulrich Stern
3个回答

15

作为该帖子的作者已经找到了解决方案,但并没有将其添加为答案,因此我在这里提供解决方案。

您必须在设置所需分辨率之前设置编解码器:

this->camRef.set(CV_CAP_PROP_FOURCC,CV_FOURCC('M','J','P','G'));
this->camRef.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
this->camRef.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);

谢谢!它按照说明工作了!另一方面,我想提到的是,尽管这将允许fullHD@30分辨率,但图像质量可能非常差(必须高压缩比以满足USB 2.0的带宽限制)。 - cbuchart

3

使用Logitech C922,需要:

capture.open(CV_CAP_DSHOW);
capture.set(CV_CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));
capture.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);

1

在设置任何内容之前,尝试从捕获中获取第一帧:

VideoCapture cap(0);
if(!cap.isOpened()) 
return -1;  

Mat frame;
cap >> frame;
double fps;
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1080.0);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 1920.0);
//add the loop here

检查是否可以在不设置MJPG的情况下工作。如果可以,尝试使用MJPG。

对我来说,有些奇怪的是,在设置任何内容之前必须先获取第一帧,但这是唯一能让我(Windows 7 32位)正常工作的方法。



//编辑:
您可以尝试使用不同的API-请参见我的答案的第二部分:https://dev59.com/_2zXa4cB1Zd3GeqPYuBF#14188280 OpenCV默认尝试使用最佳API,但也许在您的情况下其他API效果更好。


谢谢您的回复。我尝试了您说的方法,现在我的代码在显示图像之前崩溃了。cap.read返回1,然后在尝试再次从相机读取时崩溃。 - Daniel Moodie
我已更新原始问题以展示您所请求的代码。 - Daniel Moodie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接