libuvc是一个用于USB视频设备的跨平台库,构建在libusb之上,编译libuvc时需要依赖libusb。libuvc的License为BSD,最新发布版本为0.0.6,源码地址: https://github.com/libuvc/libuvc
libuvc支持在非windows系统上直接编译,因为libuvc源码中会include pthread.h等头文件,因此在windows上并不能直接进行编译。
libuvc支持对导出标准USB视频类(USB Video Class, UVC)接口的USB视频设备进行细粒度控制,使开发人员能够为以前不受支持的设备编写驱动程序,或仅以通用方式访问UVC设备。
关于libusb的介绍可以参考:https://blog.csdn.net/fengbingchun/article/details/105712776
在linux上插入同一厂家两个相同型号的摄像头时,通过lsusb命令获取的两个摄像头设备信息是一样的,不能做出区分,此时可以通过libuvc来获取摄像头设备较为详细的信息,从此信息可以分辨出具体是从哪个摄像头上获取到的视频数据。
以下是测试代码,参考 https://ken.tossell.net/libuvc/doc/
namespace {
void cb(uvc_frame_t* frame, void* ptr)
{// We'll convert the image from YUV/JPEG to BGR, so allocate spaceuvc_frame_t* bgr = uvc_allocate_frame(frame->width * frame->height * 3);if (!bgr) {printf("unable to allocate bgr frame!\n");return;}// Do the BGR conversionuvc_error_t ret = uvc_any2bgr(frame, bgr);if (ret) {uvc_perror(ret, "uvc_any2bgr");uvc_free_frame(bgr);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);*/uvc_free_frame(bgr);
}} // namespaceint test_libuvc_get_webcam_info()
{// reference: https://ken.tossell.net/libuvc/doc/// 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.uvc_context_t* ctx = nullptr;uvc_error_t res = uvc_init(&ctx, nullptr);if (res < 0) {uvc_perror(res, "uvc_init");return res;}fprintf(stdout, "UVC initialized\n");// Locates the first attached UVC device, stores in devuvc_device_t* dev = nullptr;uvc_device_handle_t* devh = nullptr;res = uvc_find_device(ctx, &dev, 0, 0, nullptr); // filter devices: vendor_id, product_id, "serial_num"if (res < 0) {uvc_perror(res, "uvc_find_device"); // no devices found} else {fprintf(stdout, "Device found\n");// Try to open the device: requires exclusive accessres = uvc_open(dev, &devh);if (res < 0) {uvc_perror(res, "uvc_open"); // unable to open device} else {fprintf(stdout, "Device opened\n");// Print out a message containing all the information that libuvc knows about the deviceuvc_print_diag(devh, stderr);// Try to negotiate a 640x480 30 fps YUYV stream profileuvc_stream_ctrl_t ctrl;res = uvc_get_stream_ctrl_format_size(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 resultuvc_print_stream_ctrl(&ctrl, stderr);if (res < 0) {uvc_perror(res, "get_mode"); // device doesn't provide a matching streamreturn res;} else {// Start the video stream. The library will call user function cb: cb(frame, (void*) 12345)void* user_ptr = nullptr;res = uvc_start_streaming(devh, &ctrl, cb, user_ptr, 0);if (res < 0) {uvc_perror(res, "start_streaming"); // unable to start stream} else {fprintf(stdout, "Streaming...\n");uvc_set_ae_mode(devh, 1); // e.g., turn on auto exposurestd::this_thread::sleep_for(std::chrono::seconds(1)); // stream for 1 seconds// End the stream. Blocks until last callback is serviceduvc_stop_streaming(devh);fprintf(stdout, "Done streaming.\n");}}// Release our handle on the deviceuvc_close(devh);fprintf(stdout, "Device closed\n");}// Release the device descriptoruvc_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);fprintf(stdout, "UVC exited\n");return 0;
}
执行结果如下:
GitHub:https://github.com/fengbingchun/OpenCV_Test
















