不幸的是,opencv 中的 C4V2 调用无法使用我尝试使用 UVC 驱动程序开箱即用的任何相机捕获静态图像。
为了调试这个问题,我一直在尝试使用直接调用 c4v2 的 C 代码来完成此操作。
我一直在玩找到的示例代码here http://linuxtv.org/downloads/v4l-dvb-apis/v4l2grab-example.html。它使用从视频流中提取帧的方法。
您可以使用以下命令编译它:
gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` filename.c -o filename
我尝试过 3 个罗技相机。其中最好的似乎是 Logitech C910。但即便如此,它也存在重大问题。
以下是我尝试使用此代码完成相同任务时遇到的问题。
当宽度和高度设置为 1920x1080 时,它几乎每次都能工作。
当我直接从命令行查询其他可能性时,例如使用:
v4l2-ctl --list-formats-ext
我尝试了一些其他“可用”的较小尺寸,它挂在选择中等待相机释放缓冲区。
另外,当我尝试直接从命令行设置其他尺寸时,例如:
v4l2-ctl -v height=320 -v width=240 -v pixelformat=YUYV
然后检查
v4l2-ctl -V
我发现它返回正确的像素格式,但通常不是正确的大小。
显然这款相机列在UVC site http://www.ideasonboard.org/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.
事实证明,默认设置 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)