13

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

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

因此,有两种可能的方式来捕获静止图像。您可以从相机的视频流中拍摄一帧,也可以拍摄单独的照片,例如便携式数码相机。linux uvc驱动不支持第二种方式,所以只有第一种方式。但问题是,如果要从视频流中截取一帧,照片的大小不能大于视频预览窗口中的视频大小。所以,如果我想拍 2 兆像素的照片,我必须以 1600x1200 的大小开始视频流,这不太舒服(至少,在 Qt 中,视频流的大小取决于视频预览窗口的大小)。

我知道有 linux 2 API 的视频,这可能对这项任务有帮助,但我不知道如何使用它。我目前正在学习 gstreamer,但我现在不知道如何使用这些工具来做我需要的事情。

因此,我将不胜感激。我认为对于了解 Linux、GStreamer、v4l2 API 和其他特定于 linux 的东西的人来说,这不是一个难题。

顺便说一句,该程序将仅与网络摄像头 Logitech C270 HD 一起使用。

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

4

4 回答 4

5

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

为了调试我一直在尝试使用直接调用 c4v2 的 c 代码来完成此操作的问题。

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

你可以编译它:

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 网站上列为 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)
于 2014-02-12T05:02:12.243 回答
2
**Download And Install 'mplayer'** 
mplayer -vo png -frames 1 tv://
于 2013-05-04T21:10:33.583 回答
1
mplayer -vo png -frames 1 tv://

由于相机尚未准备好,可能会输出绿屏。

mplayer -vo png -frames 2 tv://

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

于 2014-05-15T04:55:55.520 回答
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 集成,:)

于 2013-05-04T21:43:51.043 回答