如何从linux上的网络摄像头捕捉静止图像

loc*_*ion 11 linux webcam photo

我正在尝试为linux编写一个C++/Qt程序,在那里我从网络摄像头拍摄静态图像照片,对照片进行一些转换(裁剪,调整大小等),并将其保存到jpeg文件中.

但我遇到了一些问题.主要问题是标准的UVC(usb视频设备类)linux驱动程序目前不支持直接静态图像捕获:http://www.ideasonboard.org/uvc/.

因此,有两种可能的方法来捕获静止图像.您可以从相机的视频流中拍摄一帧,也可以拍摄单独的照片,如数码便携式相机.linux uvc驱动程序不支持第二种方式,所以第一种方法是唯一的方法.但问题是,如果你想从视频流中取出一帧,那么照片的大小不能大于视频预览窗口中的视频大小.因此,如果我想拍摄200万像素的照片,我必须启动尺寸为1600x1200的视频流,这不太舒服(至少,在Qt中,视频流的大小取决于视频窗口大小).

我知道有linux 2 API的视频,这可能对此任务有所帮助,但我不知道如何使用它.我目前正在学习gstreamer,但我现在无法弄清楚如何使用这些工具做我需要的工作.

所以,我将不胜感激任何帮助.我认为对于熟悉Linux,GStreamer,v4l2 API和其他特定于Linux的东西的人来说,这不是一个难题.

顺便说一下,该程序将仅用于网络摄像机罗技C270 HD.

请帮我.我不知道什么API或框架可以帮助我做到这一点.可能你知道吗

San*_*awy 5

不幸的是,opencv 中的 C4V2 调用不适用于我使用 UVC 驱动程序开箱即用的任何相机捕捉静态图像。

为了调试这个问题,我一直在尝试使用直接调用 c4v2 的 c 代码来完成这个问题。

我一直在使用此处找到的示例代码。它使用从视频流中提取帧的方法。

你可以编译它:

gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` filename.c -o filename
Run Code Online (Sandbox Code Playgroud)

我已经尝试过 3 台罗技相机。最好的似乎是罗技 C910。但即使它也有重大问题。

以下是我在尝试使用此代码完成相同任务时遇到的问题。

当宽度和高度设置为 1920x1080 时,它几乎每次都能工作。

当我直接从命令行查询其他可能性时,例如:

v4l2-ctl --list-formats-ext
Run Code Online (Sandbox Code Playgroud)

我尝试了一些其他“可用”较小的尺寸,它挂在选择中等待相机释放缓冲区。

此外,当我尝试直接从命令行设置其他尺寸时,例如:

v4l2-ctl -v height=320 -v width=240 -v pixelformat=YUYV
Run Code Online (Sandbox Code Playgroud)

然后检查

v4l2-ctl -V
Run Code Online (Sandbox Code Playgroud)

我发现它返回正确的像素格式,但通常不是正确的大小。

显然,这台在 UVC 站点上列为 UVC 并且因此与 v4l2 兼容的相机不符合标准。我怀疑这对其他相机也一样糟糕。我试过的另外两个也被列为兼容网站,但有更严重的问题。

发布此信息后,我对 LogitechC910 进行了更多测试。我想我会发布结果,以防它帮助其他人。

我编写了一个脚本来测试上面提到的 v4l2 抓取器代码,用于在使用 v4l2 查询时相机声称支持的所有格式,结果如下:

640x480 => Hangs on clearing buffer
160x120 => Works
176x144 => Works
320x176 => Works
320x240 => Works
432x240 => Works
352x288 => Works
544x288 => Works
640x360 =>  Works
752x416 => Hangs on clearing buffer
800x448 => Hangs on clearing buffer
864x480 => Works
960x544 => Works
1024x576 => Works
800x600 => Works
1184x656 => Works
960x720 => Works
1280x720 => Works
1392x768 => Works
1504x832 => Works
1600x896 => Works
1280x960 => Works
1712x960 => Works
1792x1008 => Works
1920x1080 => Works
1600x1200 => Works
2048x1536 => Works
2592x1944 => Hangs on clearing buffer.
Run Code Online (Sandbox Code Playgroud)

事实证明,640x480 的默认设置不起作用,这就是我和大多数在留言板上发帖的其他人的困扰。

由于它正在抓取视频帧,因此它在启动时抓取的第一帧可能曝光不正确(通常是黑色或接近它)。我相信这是因为因为它被用作摄像机,所以它会随着它调整曝光并且不关心第一帧。我相信这也困住了我和其他人,他们将第一帧视为黑色或接近黑色,并认为这是某种错误。后面的帧有正确的曝光

事实证明,如果您避开上面列出的地雷并忽略所有错误消息,那么带有 python 包装器的 opencv 可以很好地与此相机配合使用。错误消息是由于当相机接受 v4l2 命令时它没有正确响应的事实。因此,如果您设置宽度,它实际上设置正确,但它以不正确的宽度响应。

要使用 python 包装器在 opencv 下运行,您可以执行以下操作:

import cv2
import numpy

cap = cv2.VideoCapture(0)  #ignore the errors
cap.set(3, 960)        #Set the width important because the default will timeout
                       #ignore the error or false response
cap.set(4, 544)        #Set the height ignore the errors
r, frame = cap.read()
cv2.imwrite("test.jpg", frame)
Run Code Online (Sandbox Code Playgroud)


M. *_*far 2

**Download And Install 'mplayer'** 
mplayer -vo png -frames 1 tv://
Run Code Online (Sandbox Code Playgroud)