使用 v4l2 捕获相机图像非常慢

Posted

技术标签:

【中文标题】使用 v4l2 捕获相机图像非常慢【英文标题】:Capturing camera image with v4l2 very slow 【发布时间】:2015-03-26 08:00:40 【问题描述】:

我一直致力于直接使用 v4l2 在 OpenCV 中抓取相机图像。这很好用;通过这种方式,我可以抓取 YUYV 格式的高分辨率图像(理解帧率会下降)。我无法通过 OpenCV 实现来完成这项工作。从功能上讲,它工作得很好,但性能可能会好得多。由于这是我第一次直接使用 v4l2,所以对我来说还是有点模糊。 我一直在对所有相关部分进行计时,发现 v4l2 选择方法需要一秒钟多一点的时间。当我降低时间间隔时,选择方法花费的时间更少,但比出队花费的时间要长得多(也是那一秒)。在其他功能中,相机被初始化,因此设置正确的格式等。我知道帧率会很低,没有压缩和高分辨率,但这非常低。

下面是抓图功能。我跳过了将缓冲区转换为 Mat (YUYV -> RGB) 的代码,因为我认为它现在不相关。

有人知道如何让 v4l2 更快地捕获图像吗?也许有些部分我不应该执行每个帧抓取?

谢谢!

Mat Camera::capture_image() 
Mat returnframe(10, 10, CV_8UC3);
struct v4l2_buffer buf = 0;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) 
    perror("Query Buffer");
    return returnframe;


if (-1 == xioctl(fd, VIDIOC_STREAMON, &buf.type)) 
    perror("Start Capture");
    return returnframe;


fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
struct timeval tv = 0;
tv.tv_sec = 2;
int r = select(fd + 1, &fds, NULL, NULL, &tv);
if (-1 == r) 
    perror("Waiting for Frame");
    return returnframe;


if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) 
    perror("Retrieving Frame");
    return returnframe;

//此处转换为 Mat 的代码

if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &buf.type)) 
    perror("Stop Capture");
    return returnframe;


//copy Mat and free bigbuffer, to avoid memory leak
Mat returnImg = dispimg.clone();
free(bigbuffer);
return returnImg;

【问题讨论】:

您正在开始捕捉每一帧?看起来很多人偷听 【参考方案1】:

似乎对于您调用的每一帧VIDIOC_STREAMONVIDIOC_STREAMOFF;这会增加很多开销(这几乎就像为每一帧重新启动应用程序一样)

正确的方法是:

打开设备(仅调用一次):在捕获会话开始时(例如程序启动),通过调用 VIDIOC_STREAMON 设置您的视频设备以开始流式传输/p>

捕获帧(多次调用):对于您要捕获的每一帧,仅通过调用 DQBUF/QBUF 来请求该帧(这非常快,因为设备会不断地将数据到缓冲队列中);您仍然需要致电select 以了解新框架何时可用。

关闭设备(仅调用一次):完成后,通过调用 VIDIOC_STREAMOFF

停止流式传输

【讨论】:

感谢您的回复!所以我不再使用选择功能了吗?你的意思是我必须在 DQBUF 和 QBUF 之间做出选择,还是我应该同时使用这两者? 不,你仍然使用select(知道帧何时准备好)和DQBUFdequeue buffer)和QBUFqueue缓冲区) 属于一起(你使用both);关键是,你不能在capture frame函数中调用STREAMON,而是在open device函数中调用。 好的,很好。这有很大的不同!顺序重要吗?非常感谢! 您好,我使用 30 see3cam 130 作为工业解决方案。我得到了很大的延迟

以上是关于使用 v4l2 捕获相机图像非常慢的主要内容,如果未能解决你的问题,请参考以下文章

android中相机捕获的隐式意图

控制相机采集图像并做处理

图像压缩压缩速度非常慢

通过相机扫描图像和从相机捕获图像之间有啥不同吗?

通过相机获取最近捕获的图像的路径和图像名称

在android中与相机捕获的图像叠加图像