使用C从Ubuntu中的网络摄像头拍摄图像

时间:2013-03-18 05:58:41

标签: c linux image webcam

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

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

是否有可用于执行此操作的简单C库或代码?

4 个答案:

答案 0 :(得分:1)

你看过OpenCV了吗?它对于各种图像获取和处理非常方便。拍照的过程已有详细记录,但如果您确实决定使用它,我建议您查看this之类的内容。

答案 1 :(得分:1)

我不知道有一个好的图书馆(请添加评论并告诉我是否有一个:-))。注意:对于某些用途,例如。 OpenCV很好,if it is enough for you, definitely do use it。但如果你想要更多,请继续阅读。

所以你应该编写自己的代码来使用它,这并不是特别难。以下是一个相关问题:How to use/learn Video4Linux2 (On Screen Display) Output APIs?

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

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

  • IMO必须:使用IDE /编辑器,它可以跟随符号到实际的头文件(例如在Qt Creator中,这是一个很好的纯C应用程序IDE,尽管名称,在符号上点击F2,它将转到系统标题,以显示它的定义)。在V4L2相关符号上大量使用它,并在头文件中定义和读取注释,这通常是最好的文档。

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

  • 不要在传递给IOCTL的结构体中设置值时保持懒惰。在声明结构后,始终使用memset(&ioctl_struct_var, 0, sizeof(ioctl_struct_var));将结构初始化为0,并且如果重复使用它们(除非在某些设置上执行'get-modify-set'操作,这在V4L2中很常见)。

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

  • 小步骤。通常ioctl可能无法返回您期望的内容,因此在您实际看到查询返回相机的内容之前,无需编写使用返回数据的代码。

上面提到的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);

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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