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来完成这项工作。你可以按照以下步骤来做:
- Open the devicefile of the camera (usually "/dev/video0")
- 打开相机的devicefile(通常是“/dev/video0”)
- Tell v4l2 that you want to know some capability of the device
- 告诉v4l2你想知道一些设备的性能
- Tell v4l2 to read from the device
- 告诉v4l2从设备读取。
- Tell v4l2 wich format you want to use
- 告诉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来完成这项工作。你可以按照以下步骤来做:
- Open the devicefile of the camera (usually "/dev/video0")
- 打开相机的devicefile(通常是“/dev/video0”)
- Tell v4l2 that you want to know some capability of the device
- 告诉v4l2你想知道一些设备的性能
- Tell v4l2 to read from the device
- 告诉v4l2从设备读取。
- Tell v4l2 wich format you want to use
- 告诉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;
}