1

我正在尝试使用我的网络摄像头(Creative Live!Cam Chat)以 C/C++ 拍摄图像并将其保存到某个文件夹(运行 Ubuntu)。理想情况下,尽管它不是最优雅的解决方案,但我正在寻找尽可能简单的东西。

到目前为止,我发现了 v4l2grab,我发现它非常难以理解,并且似乎也不适用于 Creative 网络摄像头(返回大小为 5Kb 的黑色图片),尽管它似乎可以与安装为我的笔记本电脑的一部分。

我可以使用任何简单的 C 库或代码来执行此操作吗?

4

4 回答 4

2

我不知道为此目的有一个好的库(请添加评论并告诉我是否有一个:-))。注意:对于某些用途,例如。OpenCV很好,如果它对你来说足够了,一定要使用它。但是,如果您想要更多,请继续阅读。

所以你应该只写你自己的代码来使用它,这并不是特别难。这是一个相关的问题:如何使用/学习 Video4Linux2(屏幕显示)输出 API?

使学习更容易的一些要点:

  • 调用 IOCTL 后,请始终检查返回状态并打印可能的错误消息。在你工作的时候你会得到很多这样的东西,所以要系统地处理它。我建议使用如下check_error所示的函数,并在任何 ioctl 调用后立即调用它。

  • IMO 必须:使用 IDE/editor,它可以跟随符号到实际的头文件(例如在 Qt Creator 中,它是一个很好的纯 C 应用程序 IDE,尽管有名称,在符号上按 F2,它甚至会进入系统头文件向您展示它的定义位置)。在 V4L2 相关的符号和定义上自由使用它,并阅读头文件中的注释,这通常是最好的文档。

  • 使用查询 ioctls 并编写函数来转储它们以良好格式返回的值。例如,有 function void dump_cap(const struct v4l2_capability &cap) {...},并为您在代码中使用的每个结构添加一个类似的函数。

  • 不要懒于在传递给 IOCTL 的结构中设置值。总是在声明结构之后将它们初始化为 0 memset(&ioctl_struct_var, 0, sizeof(ioctl_struct_var));,并且如果你重用它们(除了在某些设置上执行“get-modify-set”操作时,这在 V4L2 中很常见)。

  • 如果可能,请使用两个(或更多)不同的网络摄像头(不同的分辨率、不同的品牌),并使用两个(全部)进行测试。如果您将视频设备作为命令行参数,这是最简单的,因此您可以为您拥有的每个摄像头使用不同的参数调用您的程序。

  • 小步骤。通常 ioctls 可能不会返回您期望的结果,因此在您真正看到查询为您的相机返回的内容之前,没有必要编写使用返回数据的代码。

上面提到的check_error功能:

void check_error(int return_value_of_ioctl, const char *msg) {
    if (return_value_of_ioctl != -1) return; /* all ok */
    int eno = errno; /* just to avoid accidental clobbering of errno */
    fprintf(stderr, "error (%d) with %s: %s\n", eno, msg, strerror(eno));
    exit(1); /* optional, depending on how you want to work with your code */
}

在每个 ioctl 之后立即调用它,例如:

struct v4l2_capability cap;
setmem(&cap, 0, sizeof(cap));
int r=ioctl(fd, VIDIOC_QUERYCAP, &cap); 
check_error(r, "VIDIOC_QUERYCAP");
dump_querycap(&cap);
于 2013-03-18T07:59:56.707 回答
2

您可以使用 OpenCV。使用cvCreatecameraCapture(您可以使用参数 0 调用它以访问故障凸轮)创建一个对象,然后调用cvQueryFrame该对象。cvQueryFrame每次调用都会返回一个帧。

于 2019-02-18T05:00:16.617 回答
1

看看uvccapture源代码。它非常简单,但标准 C,仅使用 V4L2 接口。OpenCV也可以,但设置和编译更复杂。

于 2013-03-18T06:09:09.897 回答
1

你看过OpenCV吗?它对于各种图像获取和处理都非常方便。拍照的过程是有据可查的,但我建议你看看这样的东西如果你确实决定使用它。

于 2013-03-18T06:03:40.340 回答