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

时间:2013-05-04 21:02:15

标签: 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或框架可以帮助我做到这一点。你可能知道吗。

4 个答案:

答案 0 :(得分:3)

不幸的是,opencv中的C4V2调用对于我使用UVC驱动程序开箱即用的任何相机进行静态图像捕获都不起作用。

要调试我一直在尝试用c代码直接调用c4v2来完成此任务的问题。

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

你可以用:

编译它
gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` filename.c -o filename

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

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

每次宽度和高度都设置为1920x1080时,它几乎可以正常工作。

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

v4l2-ctl --list-formats-ext

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

当我尝试使用例如:

直接从命令行设置其他大小时
v4l2-ctl -v height=320 -v width=240 -v pixelformat=YUYV

然后检查

v4l2-ctl -V

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

显然,UVC site上列出的这款相机为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)

答案 1 :(得分:2)

**Download And Install 'mplayer'** 
mplayer -vo png -frames 1 tv://

答案 2 :(得分:1)

mplayer -vo png -frames 1 tv://

可能会提供绿屏输出,因为相机尚未就绪。

mplayer -vo png -frames 2 tv://

您可以尝试增加帧数并选择相机提供正确图像的数字。

答案 3 :(得分:0)

这个节目怎么样?

#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
    VideoCapture webcam;
    webcam.open(0);
    Mat frame;
    char key;

    while(true)
    {
        webcam >> frame;
        imshow("My Webcam",frame);
        key = waitKey(10);

        if(key=='s')
        break;
    }
    imwrite("webcam_capture.jpg", frame);
    webcam.release();
    return 0;
}

这将捕获网络摄像头允许的最大尺寸的图片。现在,您可以使用Qt添加效果或调整捕获的图像大小。 OpenCV非常容易与Qt集成,:))