Có thư viện c nào để tải video từ webcam trên linux không?Thư viện webcam cho C trên Linux?
Trả lời
Đặt cược tốt nhất của bạn có thể là: video4linux (V4L)
Thật dễ sử dụng và mạnh mẽ.
Rất nhiều người trong chúng ta sử dụng OpenCV (cross-platform thư viện Computer Vision, hiện trên v2.1)
Đoạn sau lấy khung hình từ máy ảnh, chuyển đổi chúng sang dạng grayscale và hiển thị chúng trên màn hình:
#include <stdio.h>
#include "cv.h"
#include "highgui.h"
typedef IplImage* (*callback_prototype)(IplImage*);
/*
* make_it_gray: custom callback to convert a colored frame to its grayscale version.
* Remember that you must deallocate the returned IplImage* yourself after calling this function.
*/
IplImage* make_it_gray(IplImage* frame)
{
// Allocate space for a new image
IplImage* gray_frame = 0;
gray_frame = cvCreateImage(cvSize(frame->width, frame->height), frame->depth, 1);
if (!gray_frame)
{
fprintf(stderr, "!!! cvCreateImage failed!\n");
return NULL;
}
cvCvtColor(frame, gray_frame, CV_RGB2GRAY);
return gray_frame;
}
/*
* process_video: retrieves frames from camera and executes a callback to do individual frame processing.
* Keep in mind that if your callback takes too much time to execute, you might loose a few frames from
* the camera.
*/
void process_video(callback_prototype custom_cb)
{
// Initialize camera
CvCapture *capture = 0;
capture = cvCaptureFromCAM(-1);
if (!capture)
{
fprintf(stderr, "!!! Cannot open initialize webcam!\n");
return;
}
// Create a window for the video
cvNamedWindow("result", CV_WINDOW_AUTOSIZE);
IplImage* frame = 0;
char key = 0;
while (key != 27) // ESC
{
frame = cvQueryFrame(capture);
if(!frame)
{
fprintf(stderr, "!!! cvQueryFrame failed!\n");
break;
}
// Execute callback on each frame
IplImage* processed_frame = (*custom_cb)(frame);
// Display processed frame
cvShowImage("result", processed_frame);
// Release resources
cvReleaseImage(&processed_frame);
// Exit when user press ESC
key = cvWaitKey(10);
}
// Free memory
cvDestroyWindow("result");
cvReleaseCapture(&capture);
}
int main(int argc, char **argv)
{
process_video(make_it_gray);
return 0;
}
Liên kết mới http://opencv.org/ – GramThanos
v4l2
ví dụ chính thức
gì bạn nhận được:
./v4l2grab
: chụp một vài bức ảnh chụp các tập tinoutNNN.ppm
./v4l2gl
: hiển thị video trực tiếp trên cửa sổ sử dụng một kết cấu OpenGL và thô X11 cửa sổ (cộng với thị trường bất động củagluLookAt
cho biện pháp tốt) (vẽ mắt, hey!).
Làm thế nào để có được nó trên Ubuntu 16.04:
sudo apt-get install libv4l-dev
sudo apt-get build-dep libv4l-dev
git clone git://linuxtv.org/v4l-utils.git
cd v4l-utils
# Matching the installed version of dpkg -s libv4l-dev
git checkout v4l-utils-1.10.0
./bootstrap.sh
./configure
make
# TODO: fails halfway, but it does not matter for us now.
cd contrib/tests
make
Nó cũng rất dễ dàng để sử dụng những ví dụ bên ngoài của cây Git, chỉ cần sao chép chúng ra, làm tương đối bao gồm ""
tuyệt đối <>
, và loại bỏ config.h
. Tôi đã làm điều đó cho bạn tại địa chỉ: https://github.com/cirosantilli/cpp-cheat/tree/09fe73d248f7da2e9c9f3eff2520a143c259f4a6/v4l2
dụ tối thiểu từ tài liệu
Các tài liệu 4.9.0 chứa những gì dường như là một phiên bản tối thiểu của ./v4l2grab
tại https://linuxtv.org/downloads/v4l-dvb-apis-new/uapi/v4l/v4l2grab-example.html. Tôi cần phải vá nó một cách tối thiểu và tôi đã gửi bản vá đến http://www.spinics.net/lists/linux-media/ (tài liệu của họ sống trong cây hạt nhân Linux như đầu tiên, gọn gàng), nơi mà nó bị bỏ qua.
Cách sử dụng:
gcc v4l2grab.c -lv4l2
./a.out
đang Patched:
/* V4L2 video picture grabber
Copyright (C) 2009 Mauro Carvalho Chehab <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/videodev2.h>
#include <libv4l2.h>
#define CLEAR(x) memset(&(x), 0, sizeof(x))
struct buffer {
void *start;
size_t length;
};
static void xioctl(int fh, int request, void *arg)
{
int r;
do {
r = v4l2_ioctl(fh, request, arg);
} while (r == -1 && ((errno == EINTR) || (errno == EAGAIN)));
if (r == -1) {
fprintf(stderr, "error %d, %s\\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
int main(int argc, char **argv)
{
struct v4l2_format fmt;
struct v4l2_buffer buf;
struct v4l2_requestbuffers req;
enum v4l2_buf_type type;
fd_set fds;
struct timeval tv;
int r, fd = -1;
unsigned int i, n_buffers;
char *dev_name = "/dev/video0";
char out_name[256];
FILE *fout;
struct buffer *buffers;
fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
if (fd < 0) {
perror("Cannot open device");
exit(EXIT_FAILURE);
}
CLEAR(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
xioctl(fd, VIDIOC_S_FMT, &fmt);
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
printf("Libv4l didn't accept RGB24 format. Can't proceed.\\n");
exit(EXIT_FAILURE);
}
if ((fmt.fmt.pix.width != 640) || (fmt.fmt.pix.height != 480))
printf("Warning: driver is sending image at %dx%d\\n",
fmt.fmt.pix.width, fmt.fmt.pix.height);
CLEAR(req);
req.count = 2;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_REQBUFS, &req);
buffers = calloc(req.count, sizeof(*buffers));
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
xioctl(fd, VIDIOC_QUERYBUF, &buf);
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start = v4l2_mmap(NULL, buf.length,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start) {
perror("mmap");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < n_buffers; ++i) {
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
xioctl(fd, VIDIOC_QBUF, &buf);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMON, &type);
for (i = 0; i < 20; i++) {
do {
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Timeout. */
tv.tv_sec = 2;
tv.tv_usec = 0;
r = select(fd + 1, &fds, NULL, NULL, &tv);
} while ((r == -1 && (errno = EINTR)));
if (r == -1) {
perror("select");
return errno;
}
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_DQBUF, &buf);
sprintf(out_name, "out%03d.ppm", i);
fout = fopen(out_name, "w");
if (!fout) {
perror("Cannot open image");
exit(EXIT_FAILURE);
}
fprintf(fout, "P6\n%d %d 255\n",
fmt.fmt.pix.width, fmt.fmt.pix.height);
fwrite(buffers[buf.index].start, buf.bytesused, 1, fout);
fclose(fout);
xioctl(fd, VIDIOC_QBUF, &buf);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMOFF, &type);
for (i = 0; i < n_buffers; ++i)
v4l2_munmap(buffers[i].start, buffers[i].length);
v4l2_close(fd);
return 0;
}
header chỉ đối tượng phiên bản định hướng để tái sử dụng
Trích từ ví dụ trong tài liệu, nhưng trong một hình thức mà làm nó siêu dễ dàng để tái sử dụng.
common_v4l2.h
:
#ifndef COMMON_V4L2_H
#define COMMON_V4L2_H
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/types.h>
#include <libv4l2.h>
#include <linux/videodev2.h>
#define COMMON_V4L2_CLEAR(x) memset(&(x), 0, sizeof(x))
typedef struct {
void *start;
size_t length;
} CommonV4l2_Buffer;
typedef struct {
int fd;
CommonV4l2_Buffer *buffers;
struct v4l2_buffer buf;
unsigned int n_buffers;
} CommonV4l2;
void CommonV4l2_xioctl(int fh, unsigned long int request, void *arg)
{
int r;
do {
r = v4l2_ioctl(fh, request, arg);
} while (r == -1 && ((errno == EINTR) || (errno == EAGAIN)));
if (r == -1) {
fprintf(stderr, "error %d, %s\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
void CommonV4l2_init(CommonV4l2 *this, char *dev_name, unsigned int x_res, unsigned int y_res) {
enum v4l2_buf_type type;
struct v4l2_format fmt;
struct v4l2_requestbuffers req;
unsigned int i;
this->fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
if (this->fd < 0) {
perror("Cannot open device");
exit(EXIT_FAILURE);
}
COMMON_V4L2_CLEAR(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = x_res;
fmt.fmt.pix.height = y_res;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
CommonV4l2_xioctl(this->fd, VIDIOC_S_FMT, &fmt);
if ((fmt.fmt.pix.width != x_res) || (fmt.fmt.pix.height != y_res))
printf("Warning: driver is sending image at %dx%d\n",
fmt.fmt.pix.width, fmt.fmt.pix.height);
COMMON_V4L2_CLEAR(req);
req.count = 2;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
CommonV4l2_xioctl(this->fd, VIDIOC_REQBUFS, &req);
this->buffers = calloc(req.count, sizeof(*this->buffers));
for (this->n_buffers = 0; this->n_buffers < req.count; ++this->n_buffers) {
COMMON_V4L2_CLEAR(this->buf);
this->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
this->buf.memory = V4L2_MEMORY_MMAP;
this->buf.index = this->n_buffers;
CommonV4l2_xioctl(this->fd, VIDIOC_QUERYBUF, &this->buf);
this->buffers[this->n_buffers].length = this->buf.length;
this->buffers[this->n_buffers].start = v4l2_mmap(NULL, this->buf.length,
PROT_READ | PROT_WRITE, MAP_SHARED, this->fd, this->buf.m.offset);
if (MAP_FAILED == this->buffers[this->n_buffers].start) {
perror("mmap");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < this->n_buffers; ++i) {
COMMON_V4L2_CLEAR(this->buf);
this->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
this->buf.memory = V4L2_MEMORY_MMAP;
this->buf.index = i;
CommonV4l2_xioctl(this->fd, VIDIOC_QBUF, &this->buf);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
CommonV4l2_xioctl(this->fd, VIDIOC_STREAMON, &type);
}
void CommonV4l2_update_image(CommonV4l2 *this) {
fd_set fds;
int r;
struct timeval tv;
do {
FD_ZERO(&fds);
FD_SET(this->fd, &fds);
/* Timeout. */
tv.tv_sec = 2;
tv.tv_usec = 0;
r = select(this->fd + 1, &fds, NULL, NULL, &tv);
} while ((r == -1 && (errno == EINTR)));
if (r == -1) {
perror("select");
exit(EXIT_FAILURE);
}
COMMON_V4L2_CLEAR(this->buf);
this->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
this->buf.memory = V4L2_MEMORY_MMAP;
CommonV4l2_xioctl(this->fd, VIDIOC_DQBUF, &this->buf);
CommonV4l2_xioctl(this->fd, VIDIOC_QBUF, &this->buf);
}
char * CommonV4l2_get_image(CommonV4l2 *this) {
return ((char *)this->buffers[this->buf.index].start);
}
size_t CommonV4l2_get_image_size(CommonV4l2 *this) {
return this->buffers[this->buf.index].length;
}
void CommonV4l2_deinit(CommonV4l2 *this) {
unsigned int i;
enum v4l2_buf_type type;
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
CommonV4l2_xioctl(this->fd, VIDIOC_STREAMOFF, &type);
for (i = 0; i < this->n_buffers; ++i)
v4l2_munmap(this->buffers[i].start, this->buffers[i].length);
v4l2_close(this->fd);
free(this->buffers);
}
#endif
main.c
:
#include <stdio.h>
#include <stdlib.h>
#include "common_v4l2.h"
static void save_ppm(
unsigned int i,
unsigned int x_res,
unsigned int y_res,
size_t data_lenght,
char *data
) {
FILE *fout;
char out_name[256];
sprintf(out_name, "out%03d.ppm", i);
fout = fopen(out_name, "w");
if (!fout) {
perror("error: fopen");
exit(EXIT_FAILURE);
}
fprintf(fout, "P6\n%d %d 255\n", x_res, y_res);
fwrite(data, data_lenght, 1, fout);
fclose(fout);
}
int main(void) {
CommonV4l2 common_v4l2;
char *dev_name = "/dev/video0";
struct buffer *buffers;
unsigned int
i,
x_res = 640,
y_res = 480
;
CommonV4l2_init(&common_v4l2, dev_name, x_res, y_res);
for (i = 0; i < 20; i++) {
CommonV4l2_update_image(&common_v4l2);
save_ppm(
i,
x_res,
y_res,
CommonV4l2_get_image_size(&common_v4l2),
CommonV4l2_get_image(&common_v4l2)
);
}
CommonV4l2_deinit(&common_v4l2);
return EXIT_SUCCESS;
}
SDL
Quay video là trong roadma của họ p: https://wiki.libsdl.org/Roadmap và tôi đặt cược nó sẽ bọc v4l trên Linux.
Sẽ thật ngọt ngào khi chúng tôi nhận được lớp di động đó, ít bị sưng hơn so với OpenCV.
- 1. Lập trình webcam trên Linux
- 2. Thư viện được chia sẻ Linux C++
- 3. Chụp ảnh webcam USB trong C++ KHÔNG openCV (LINUX)
- 4. Thư viện UUID cho C?
- 5. Thư viện C# trên iOS
- 6. Vẽ thư viện cho C#
- 7. Cách khởi tạo thư viện dùng chung trên Linux
- 8. Thư viện tệp cấu hình Linux
- 9. Cách chụp ảnh tĩnh từ webcam trên linux
- 10. Thư viện P2P cho C++
- 11. GUI/thư viện TUI linux
- 12. Thư viện toán học nhanh hơn glibc trên x86_64/linux?
- 13. Thư viện Linux C hoặc C++ cho các chuỗi khác biệt và vá?
- 14. thư viện mp3 C++
- 15. Thư viện C để đọc phiên bản EXE từ Linux?
- 16. Tách thư viện chia sẻ linux
- 17. thư viện sqlite c trên mac os?
- 18. Windows gói-manager cho C++ thư viện
- 19. Thư viện băm STM cho C (glib?)
- 20. Có thư viện máy khách MS-DRM cho Linux không?
- 21. Tùy chọn đọc webcam bằng Python/Linux
- 22. Thư viện chuẩn dành cho người lớn cho C
- 23. Thư viện xem thư mục/tệp trong C/C++
- 24. API Socket hoặc thư viện cho C++?
- 25. Làm thế nào để gọi thư viện c từ mã lắp ráp trên Linux?
- 26. Thư viện C++ tương tự như C#?
- 27. Tạo thư viện dùng gcc trên Linux và MinGW trên Windows
- 28. Đo kích thước thư viện trong Linux
- 29. Thư viện C chuẩn ở đâu trên Mac OS X?
- 30. Thư viện mật mã cho C++
Bạn có thể cho biết thư viện nào bạn đã sử dụng không? – russoue