libuvc介绍及简单使用

x33g5p2x  于2021-11-11 转载在 其他  
字(3.8k)|赞(0)|评价(0)|浏览(700)

    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 space
     uvc_frame_t* bgr = uvc_allocate_frame(frame->width * frame->height * 3);
    if (!bgr) {
        printf("unable to allocate bgr frame!\n");
        return;
    }

    // Do the BGR conversion
    uvc_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);
}

} // namespace

int 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 dev
    uvc_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 access
        res = 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 device
            uvc_print_diag(devh, stderr);
            // Try to negotiate a 640x480 30 fps YUYV stream profile
            uvc_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 result
            uvc_print_stream_ctrl(&ctrl, stderr);
            if (res < 0) {
                uvc_perror(res, "get_mode"); // device doesn't provide a matching stream
                return 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 exposure
                    std::this_thread::sleep_for(std::chrono::seconds(1)); // stream for 1 seconds
                    // End the stream. Blocks until last callback is serviced
                    uvc_stop_streaming(devh);
                    fprintf(stdout, "Done streaming.\n");
                }
            }
            // Release our handle on the device
            uvc_close(devh);
            fprintf(stdout, "Device closed\n");
        }
        // 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);
    fprintf(stdout, "UVC exited\n");

    return 0;
}

    执行结果如下:


 

   GitHubhttps://github.com/fengbingchun/OpenCV_Test

相关文章

微信公众号

最新文章

更多