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

c++, webcam

Solution

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

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

- Open the devicefile of the camera (usually "/dev/video0")

- Tell v4l2 that you want to know some capability of the device

- Tell v4l2 to read from the device

- Tell v4l2 wich format you want to use

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.

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.

#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;
}

Problem

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. 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?

Original source