如何在libuvc中获取/设置相机像素格式和分辨率?

问题描述 投票:0回答:1

关于libuvc,我有2个问题,

  1. 如何从相机获取所有相机像素格式和分辨率?
  2. 如何设置相机像素格式和分辨率?

详情请参考https://github.com/libuvc/libuvc

感谢您的帮助。

c++ camera
1个回答
0
投票

例如,我的相机中有两种像素格式(YUYV 和 MJPEG), 我的可行代码如下,

//==================================================================
struct SCameraFrame
{
    enum uvc_frame_format pixelFormat;
    int width;
    int height;
    int fps;

    SCameraFrame()
    {
        pixelFormat = UVC_FRAME_FORMAT_ANY;
        width = 640;
        height = 480;
        fps = 30;
    }
};
//==================================================================
void yourCallbackFunction(uvc_frame_t *frame, void *ptr)
{
  // Your capture-image callback function.
  // Please refer https://github.com/libuvc/libuvc/blob/master/src/example.c 
}
//==================================================================
void MainWindow::onComboboxCurrentIndexChanged(int index)
{
    resolutionIndex = index;

    setCameraPixelFormatAndResolution();
}
//==================================================================
void MainWindow::getCameraPixelFormatAndResolution(void)
{
    if(pUvcDeviceHandle == 0)
    {
        qDebug() << "pUvcDeviceHandle = 0 @ MainWindow::getCameraPixelFormatAndResolution()";
        return;
    }

    const uvc_format_desc_t* format_desc = uvc_get_format_descs(pUvcDeviceHandle);

    if(format_desc == 0)
    {
        qDebug() << "format_desc = 0 @ MainWindow::getCameraPixelFormatAndResolution()";
        return;
    }

    vctMyCameraFrame.clear();
    std::vector<SCameraFrame>().swap(vctMyCameraFrame);

    // ****** find the 1st pixel format.
    SCameraFrame cf;
    uvc_frame_desc_t* frame_desc = format_desc->frame_descs;
    frame_desc = format_desc->frame_descs;

    while(true)
    {
        qDebug() << "%%%%%%";

        switch (format_desc->bDescriptorSubtype)
        {
        case UVC_VS_FORMAT_MJPEG:
            cf.pixelFormat = UVC_FRAME_FORMAT_MJPEG;
            qDebug() << "UVC_FRAME_FORMAT_MJPEG";
            break;
        case UVC_VS_FORMAT_FRAME_BASED:
            cf.pixelFormat = UVC_FRAME_FORMAT_H264;
            qDebug() << "UVC_FRAME_FORMAT_H264";
            break;
        default:
            cf.pixelFormat = UVC_FRAME_FORMAT_YUYV;
            qDebug() << "UVC_FRAME_FORMAT_YUYV";
            break;
        }

        if (frame_desc)
        {
            cf.width = frame_desc->wWidth;
            cf.height = frame_desc->wHeight;
            cf.fps = 10000000 / frame_desc->dwDefaultFrameInterval;

            qDebug() << "frame width = " << cf.width;
            qDebug() << "frame height = " << cf.height;
            qDebug() << "fps = " << cf.fps;
        }

        vctMyCameraFrame.push_back(cf);

        if(frame_desc->next == NULL)
            break;

        frame_desc = frame_desc->next;
    }

    if(format_desc->next == NULL)
        return;

    // ****** find the 2nd pixel format.

    const uvc_format_desc_t* format_desc1 = format_desc->next;
    frame_desc = format_desc1->frame_descs;

    while(true)
    {
        qDebug() << "%%%%%%";

        switch (format_desc1->bDescriptorSubtype)
        {
        case UVC_VS_FORMAT_MJPEG:
            cf.pixelFormat = UVC_FRAME_FORMAT_MJPEG;
            qDebug() << "UVC_FRAME_FORMAT_MJPEG";
            break;
        case UVC_VS_FORMAT_FRAME_BASED:
            cf.pixelFormat = UVC_FRAME_FORMAT_H264;
            qDebug() << "UVC_FRAME_FORMAT_H264";
            break;
        default:
            cf.pixelFormat = UVC_FRAME_FORMAT_YUYV;
            qDebug() << "UVC_FRAME_FORMAT_YUYV";
            break;
        }

        if (frame_desc)
        {
            cf.width = frame_desc->wWidth;
            cf.height = frame_desc->wHeight;
            cf.fps = 10000000 / frame_desc->dwDefaultFrameInterval;

            qDebug() << "frame width = " << cf.width;
            qDebug() << "frame height = " << cf.height;
            qDebug() << "fps = " << cf.fps;
        }

        vctMyCameraFrame.push_back(cf);

        if(frame_desc->next == NULL)
            break;

        frame_desc = frame_desc->next;
    }

    qDebug() << "~~~~~~";
}
//==================================================================
void MainWindow::setCameraPixelFormatAndResolution(void)
{
    if(pUvcDeviceHandle == 0)
    {
        qDebug() << "pUvcDeviceHandle = 0 @ MainWindow::setCameraPixelFormatAndResolution()";
        return;
    }

    if(vctMyCameraFrame.size() < 1)
    {
        qDebug() << "vctMyCameraFrame.size() < 1 @ MainWindow::setCameraPixelFormatAndResolution()";
        return;
    }

    if(resolutionIndex < 0)
    {
        qDebug() << "resolutionIndex < 0 @ MainWindow::setCameraPixelFormatAndResolution()";
        return;
    }

    uvc_stop_streaming(pUvcDeviceHandle);

    enum uvc_frame_format frame_format = vctMyCameraFrame[resolutionIndex].pixelFormat;
    int frame_width = vctMyCameraFrame[resolutionIndex].width;
    int frame_height = vctMyCameraFrame[resolutionIndex].height;
    int fps = vctMyCameraFrame[resolutionIndex].fps;

#if 1
    QString str_format = frame_format == UVC_FRAME_FORMAT_MJPEG ? "MJPEG" : "YUYV";
    qDebug() << "set format = " << str_format;
    qDebug() << "set width = " << QString::number(frame_width);
    qDebug() << "set height = " << QString::number(frame_height);
    qDebug() << "set fps = " << QString::number(fps);
#endif

    uvc_stream_ctrl_t uvc_ctrl;

    // Try to negotiate a stream profile.
    uvc_error_t res = uvc_get_stream_ctrl_format_size(
        pUvcDeviceHandle,
        &uvc_ctrl, // result stored in ctrl.
        frame_format,
        frame_width,
        frame_height,
        fps );

    if (res < UVC_SUCCESS)
    {
        qDebug() << "uvc_get_stream_ctrl_format_size() is failed @ MainWindow::setCameraPixelFormatAndResolution()";
        return;
    }

    res = uvc_start_streaming(pUvcDeviceHandle, &uvc_ctrl, yourCallbackFunction, 0, 0);

    if (res < UVC_SUCCESS)
    {
        qDebug() << "uvc_start_streaming() is failed @ MainWindow::setCameraPixelFormatAndResolution()";
        return;
    }

    qDebug() << "uvc_start_streaming() is successful @ MainWindow::setCameraPixelFormatAndResolution()";
}
© www.soinside.com 2019 - 2024. All rights reserved.