USB网络摄像头图像捕获在没有openCV(LINUX)的C++中

USB webcam image capture in C++ WITHOUT openCV (LINUX)

本文关键字:LINUX openCV C++ 摄像头 网络 图像 USB      更新时间:2023-10-16

如何使用C++用网络摄像头捕获图像并将其保存到磁盘?由于硬件问题,我无法使用OPENCV。usb网络摄像头可以与其他程序配合使用,如mplayer、cheese、gpicview、ffmpeg等。

我听说V4L能够做到这一点,但它有C++库吗?有人能给我看一个C++的例子吗?

这很容易,在激活一些ioctl以控制摄像头后,您可以在视频设备上执行read

您可以将v4l2用于此作业。你可以在这些步骤中做到这一点:

  1. 打开相机的设备文件(通常为"/dev/video0")
  2. 告诉v4l2您想了解设备的某些功能
  3. 告诉v4l2从设备中读取
  4. 告诉v4l2您要使用的格式

这是我在这份工作中使用的一个实现。它将设置相机以320x240像素拍摄视频,但您可以读取分辨率,相机能够从v4l2_capability结构中读取。

此外,我还没有在与PS2 EyeToy不同的相机上测试过代码,但它主要来自一个名为qv4l2的示例程序(您可以从这里获得)。这个程序应该可以解决你通常在那里看到的所有其他问题。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>              /* low-level i/o */
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
static int xioctl(int fh, int request, void *arg)
{
    int r;
    do {
        r = ioctl(fh, request, arg);
    } while (-1 == r && EINTR == errno);
    return r;
}
int allocCamera(const char* file) 
{
    struct v4l2_capability cap;
    struct v4l2_crop crop;
    struct v4l2_format fmt;
    int camera_fd = open(file, O_RDONLY);
    if (-1 == xioctl (camera_fd, VIDIOC_QUERYCAP, &cap)) {
        if (EINVAL == errno) {
            fprintf (stderr, "%s is no V4L2 devicen", file);
            exit (EXIT_FAILURE);
        } else {
            printf("nError in ioctl VIDIOC_QUERYCAPnn");
            exit(0);
        }
    }
    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
        fprintf (stderr, "%s is no video capture devicen", file);
        exit (EXIT_FAILURE);
    }
    if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
        fprintf (stderr, "%s does not support read i/on", file);
        exit (EXIT_FAILURE);
    }
    memset(&fmt, 0, sizeof(fmt));
    fmt.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width       = 320; 
    fmt.fmt.pix.height      = 240;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
    if (-1 == xioctl(camera_fd, VIDIOC_S_FMT, &fmt)) {
        printf("VIDIOC_S_FMT");
    }
    return camera_fd;
}