首页 文章

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

提问于
浏览
9

我正在尝试为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

    不幸的是,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
    **Download And Install 'mplayer'** 
    mplayer -vo png -frames 1 tv://
    
  • 3
    mplayer -vo png -frames 1 tv://
    

    由于相机尚未就绪,可能会提供绿屏输出 .

    mplayer -vo png -frames 2 tv://
    

    您可以尝试增加号码框架并选择相机提供正确图像的数字 .

  • 1

    那节目怎么样?

    #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集成,:)

相关问题