libuvc: a cross-platform library for USB video devices

https://int80k.com/libuvc/doc/
libuvc: a cross-platform library for USB video devices

libuvc is a library that supports enumeration, control and streaming for USB Video Class (UVC) devices, such as consumer webcams.

Features

Roadmap

  • Bulk-mode image capture
  • One-shot image capture
  • Improved support for standard settings
  • Support for "extended" (vendor-defined) settings

Misc.

The source code can be found at https://github.com/ktossell/libuvc. To build the library, install libusb 1.0+ and run:

$ git clone https: //github.com/ktossell/libuvc.git
$ cd libuvc
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make && make install

Example

In this example, libuvc is used to acquire images in a 30 fps, 640x480 YUV stream from a UVC device such as a standard webcam.

#include "libuvc/libuvc.h"
#include <stdio.h>
/* This callback function runs once per frame. Use it to perform any
* quick processing you need, or have it put the frame into your application's
* input queue. If this function takes too long, you'll start losing frames. */
void cb( uvc_frame_t *frame, void *ptr) {
uvc_frame_t *bgr;
/* We'll convert the image from YUV/JPEG to BGR, so allocate space */
bgr = uvc_allocate_frame(frame-> width * frame-> height * 3);
if (!bgr) {
printf( "unable to allocate bgr frame!");
return;
}
/* Do the BGR conversion */
ret = uvc_any2bgr(frame, bgr);
if (ret) {
uvc_perror(ret, "uvc_any2bgr");
return;
}
/* Call a user function:
*
* my_type *my_obj = (*my_type) ptr;
* my_user_function(ptr, bgr);
* my_other_function(ptr, bgr->data, bgr->width, bgr->height);
*/
/* Call a C++ method:
*
* my_type *my_obj = (*my_type) ptr;
* my_obj->my_func(bgr);
*/
/* Use opencv.highgui to display the image:
*
* cvImg = cvCreateImageHeader(
* cvSize(bgr->width, bgr->height),
* IPL_DEPTH_8U,
* 3);
*
* cvSetData(cvImg, bgr->data, bgr->width * 3);
*
* cvNamedWindow("Test", CV_WINDOW_AUTOSIZE);
* cvShowImage("Test", cvImg);
* cvWaitKey(10);
*
* cvReleaseImageHeader(&cvImg);
*/
}
int main( int argc, char **argv) {
uvc_context_t *ctx;
uvc_device_t *dev;
uvc_device_handle_t *devh;
/* Initialize a UVC service context. Libuvc will set up its own libusb
* context. Replace NULL with a libusb_context pointer to run libuvc
* from an existing libusb context. */
res = uvc_init(&ctx, NULL);
if (res < 0) {
uvc_perror(res, "uvc_init");
return res;
}
puts( "UVC initialized");
/* Locates the first attached UVC device, stores in dev */
ctx, &dev,
0, 0, NULL); /* filter devices: vendor_id, product_id, "serial_num" */
if (res < 0) {
uvc_perror(res, "uvc_find_device"); /* no devices found */
} else {
puts( "Device found");
/* Try to open the device: requires exclusive access */
res = uvc_open(dev, &devh);
if (res < 0) {
uvc_perror(res, "uvc_open"); /* unable to open device */
} else {
puts( "Device opened");
/* Print out a message containing all the information that libuvc
* knows about the device */
uvc_print_diag(devh, stderr);
/* Try to negotiate a 640x480 30 fps YUYV stream profile */
devh, &ctrl, /* result stored in ctrl */
UVC_FRAME_FORMAT_YUYV, /* YUV 422, aka YUV 4:2:2. try _COMPRESSED */
640, 480, 30 /* width, height, fps */
);
/* Print out the result */
uvc_print_stream_ctrl(&ctrl, stderr);
if (res < 0) {
uvc_perror(res, "get_mode"); /* device doesn't provide a matching stream */
} else {
/* Start the video stream. The library will call user function cb:
* cb(frame, (void*) 12345)
*/
res = uvc_start_streaming(devh, &ctrl, cb, 12345, 0);
if (res < 0) {
uvc_perror(res, "start_streaming"); /* unable to start stream */
} else {
puts( "Streaming...");
uvc_set_ae_mode(devh, 1); /* e.g., turn on auto exposure */
sleep(10); /* stream for 10 seconds */
/* End the stream. Blocks until last callback is serviced */
puts( "Done streaming.");
}
}
/* Release our handle on the device */
uvc_close(devh);
puts( "Device closed");
}
/* Release the device descriptor */
uvc_unref_device(dev);
}
/* Close the UVC context. This closes and cleans up any existing device handles,
* and it closes the libusb context if one was not provided. */
uvc_exit(ctx);
puts( "UVC exited");
return 0;
}

V4L2 (Video for Linux 2) is a kernel API that provides an interface for capturing and manipulating video devices on Linux. OpenCV is a widely used computer vision library that provides various functionalities for image and video processing. Qt is a cross-platform application framework that allows you to develop graphical user interfaces. If you want to work with V4L2, OpenCV, and Qt together, you can use OpenCV to capture video frames from a V4L2 device and then use Qt to display the captured frames in a graphical user interface. Here are the steps you can follow: 1. Install the necessary libraries: - Install V4L2 library: `sudo apt-get install libv4l-dev` - Install OpenCV library: You can either download it from the official website or install it using package manager (e.g., `pip install opencv-python`) 2. Include the required headers in your C++ code: ```cpp #include <linux/videodev2.h> // V4L2 headers #include <opencv2/opencv.hpp> // OpenCV headers #include <QtWidgets/QApplication> // Qt headers ``` 3. Use V4L2 to capture video frames: ```cpp int fd; fd = open("/dev/video0", O_RDWR); // Open the V4L2 device // Set up video capture parameters struct v4l2_format fmt; // ... // Request buffers from the V4L2 device struct v4l2_requestbuffers reqbuf; // ... // Queue the buffers for capturing struct v4l2_buffer buf; // ... // Start capturing frames enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ioctl(fd, VIDIOC_STREAMON, &type); // Capture frames for (int i = 0; i < numFrames; ++i) { // Dequeue a buffer // ... // Process the captured frame using OpenCV cv::Mat frame; // ... // Display the frame using Qt QImage image(frame.data, frame.cols, frame.rows, QImage::Format_RGB888); // ... } // Cleanup and close the V4L2 device // ... ``` 4. Use Qt to display the frames: ```cpp QApplication app(argc, argv); QWidget window; QLabel label(&window); label.setFixedSize(frame.cols, frame.rows); label.setPixmap(QPixmap::fromImage(image)); label.show(); return app.exec(); ``` Remember to handle error checking, memory management, and other necessary operations according to your application's needs.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值