没有openCV (LINUX)的c++ USB网络摄像机图像捕获

时间:2022-06-20 21:15:01

How do I capture an image with my webcam using C++ and save it to disk? I cannot use OPENCV due to hardware problems. The usb webcam does work with other programs such as mplayer, cheese, gpicview, ffmpeg, etc.

如何使用c++用网络摄像头捕获图像并保存到磁盘?由于硬件问题,我不能使用OPENCV。usb网络摄像头可以和其他程序一起工作,比如mplayer, cheese, gpicview, ffmpeg等等。

I heard V4L is capable of doing this, but does it have any C++ libraries? Can anybody show me a C++ example on how to do this?

我听说V4L可以做到这一点,但是它有c++库吗?有人能给我举个c++的例子吗?

1 个解决方案

#1


19  

It is quite easy, you can do read on a videodevice, after you have activated some ioctls to get the cam under your control.

这很容易,你可以在视频设备上阅读,在你激活了一些ioctls,使凸轮在你的控制之下。

You can use v4l2 for this job. You do this in those steps:

您可以使用v4l2来完成这项工作。你可以按照以下步骤来做:

  1. Open the devicefile of the camera (usually "/dev/video0")
  2. 打开相机的devicefile(通常是“/dev/video0”)
  3. Tell v4l2 that you want to know some capability of the device
  4. 告诉v4l2你想知道一些设备的性能
  5. Tell v4l2 to read from the device
  6. 告诉v4l2从设备读取。
  7. Tell v4l2 wich format you want to use
  8. 告诉v4l2wich格式你想使用。

Here is a implementation I use for this job. It will set the camera to capture a video in 320x240 Pixel, but you can read the resolutions, the camera is capable of from the v4l2_capability structure.

下面是我用于此工作的实现。它将设置摄像头以320x240像素捕捉视频,但您可以读取分辨率,该摄像头可以从v4l2_capability结构中获取。

Also I haven't tested the code on different Cameras than my PS2 EyeToy, but it is mostly taken from a sample program named qv4l2 (you can get it from here). This program should solve all other issues you usually see there.

此外,我还没有在不同的相机上测试过PS2的代码,但它主要是从一个名为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 device\n", file);
            exit (EXIT_FAILURE);
        } else {
            printf("\nError in ioctl VIDIOC_QUERYCAP\n\n");
            exit(0);
        }
    }

    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
        fprintf (stderr, "%s is no video capture device\n", file);
        exit (EXIT_FAILURE);
    }

    if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
        fprintf (stderr, "%s does not support read i/o\n", 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;
}

#1


19  

It is quite easy, you can do read on a videodevice, after you have activated some ioctls to get the cam under your control.

这很容易,你可以在视频设备上阅读,在你激活了一些ioctls,使凸轮在你的控制之下。

You can use v4l2 for this job. You do this in those steps:

您可以使用v4l2来完成这项工作。你可以按照以下步骤来做:

  1. Open the devicefile of the camera (usually "/dev/video0")
  2. 打开相机的devicefile(通常是“/dev/video0”)
  3. Tell v4l2 that you want to know some capability of the device
  4. 告诉v4l2你想知道一些设备的性能
  5. Tell v4l2 to read from the device
  6. 告诉v4l2从设备读取。
  7. Tell v4l2 wich format you want to use
  8. 告诉v4l2wich格式你想使用。

Here is a implementation I use for this job. It will set the camera to capture a video in 320x240 Pixel, but you can read the resolutions, the camera is capable of from the v4l2_capability structure.

下面是我用于此工作的实现。它将设置摄像头以320x240像素捕捉视频,但您可以读取分辨率,该摄像头可以从v4l2_capability结构中获取。

Also I haven't tested the code on different Cameras than my PS2 EyeToy, but it is mostly taken from a sample program named qv4l2 (you can get it from here). This program should solve all other issues you usually see there.

此外,我还没有在不同的相机上测试过PS2的代码,但它主要是从一个名为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 device\n", file);
            exit (EXIT_FAILURE);
        } else {
            printf("\nError in ioctl VIDIOC_QUERYCAP\n\n");
            exit(0);
        }
    }

    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
        fprintf (stderr, "%s is no video capture device\n", file);
        exit (EXIT_FAILURE);
    }

    if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
        fprintf (stderr, "%s does not support read i/o\n", 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;
}