【QT中使用uvc协议设置/获取usb相机的参数】

一、主要点:
1、调用Windows系统函数,搜寻目标设备:

if (m_path.isEmpty())
        return;
    // 创建系统设备枚举器
    ICreateDevEnum* dev_enum = nullptr;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC, IID_ICreateDevEnum, (void**)&dev_enum);

    if (FAILED(hr))
    {
        return;
    }

    IGraphBuilder* graph = nullptr;
    ICaptureGraphBuilder2* builder = nullptr;

    // Create the Filter Graph Manager.
    hr = CoCreateInstance(CLSID_FilterGraph, nullptr, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&graph);

    if (SUCCEEDED(hr))
    {
        // Create the Capture Graph Builder.
        hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, nullptr,
                              CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
                              (void**)&builder);
        if (SUCCEEDED(hr))
        {
            hr = builder->SetFiltergraph(graph);
        }
        else
        {
            return;
        }
    }
    else
    {
        return;
    }

    // 为类别创建枚举器
    IEnumMoniker* class_enum = nullptr;
    hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &class_enum, 0);

    if (hr != S_OK)
        return;

    IMoniker* moniker = nullptr;
    ULONG fetched;

    // 使用 IEnumMoniker 接口枚举所有的设备标识
    while (class_enum->Next(1, &moniker, &fetched) == S_OK)
    {
        IPropertyBag* prop_bag = nullptr;
        hr = moniker->BindToStorage(NULL, NULL, IID_IPropertyBag, (void**)&prop_bag);
        VARIANT var_name;
        VariantInit(&var_name);
        hr = prop_bag->Read(L"DevicePath", &var_name, NULL);
        WCHAR* devicePath = var_name.bstrVal;

        if (devicePath != nullptr) {
            QString dest = Wchat_tToQString(devicePath);
            qDebug()<<" dest:"<<dest;
            if (m_path.contains(dest))    // 设备匹配
            {
                IBaseFilter* src = nullptr;
                moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&src);

                // 查找 ProcAmp 接口,该接口控制亮度等相关参数
                src->QueryInterface(IID_IAMVideoProcAmp, (void**)&m_proc_amp);
                // 查找 Control 接口,该接口控制缩放等相关参数
                src->QueryInterface(IID_IAMCameraControl, (void**)&m_control);
                // 查找 Config  接口,该接口查询摄像头支持的格式
                builder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, src, IID_IAMStreamConfig, (void**)&m_config);

                src->Release();
                prop_bag->Release();
                moniker->Release();
                break;
            }
        }

        prop_bag->Release();
        moniker->Release();
    }

    class_enum->Release();
    dev_enum->Release();
    builder->Release();
    graph->Release();

2、获取参数(放大缩小)

UVCParameter UvcDevice::GetZoom()
{
    UVCParameter parameter;
    if (!m_control)
        return parameter;
    HRESULT hr;
    hr = m_control->GetRange(CameraControl_Zoom, &parameter.min_val,
                             &parameter.max_val, &parameter.step, &parameter.def, &parameter.flags);
    hr = m_control->Get(CameraControl_Zoom, &parameter.val, &parameter.flags);
    return parameter;
}

3、设置参数(放大缩小)

HRESULT UvcDevice::SetZoom(long value, bool isAuto)
{
    if (!m_control)
        return E_HANDLE;
    long flag = isAuto ? CameraControl_Flags_Auto : CameraControl_Flags_Manual;
    return m_control->Set(CameraControl_Zoom, value, flag);
}

二、完整代码:
1、UvcDevice.h

#ifndef UVCDEVICE_H
#define UVCDEVICE_H

#include <QString>

#include <windows.h>
#include <winnt.h>
#include <strmif.h>
#include <dshow.h>
#include <Ks.h>
#include <Ksmedia.h>
#pragma comment(lib,"Strmiids.lib")
struct UVCParameter
{
    UVCParameter()
     :result(0)
     ,min_val(0)
     ,max_val(0)
     ,val(0)
     ,def(0)
     ,step(0)
     ,flags(0)
     ,progress(0)
    {
    }
    HRESULT result;
    long min_val;
    long max_val;
    long val;
    long def;
    long step;
    long flags;
    long progress;
};

class UvcDevice
{
public:
    UvcDevice();
    ~UvcDevice();
    void SetPath(QString path);

    UVCParameter GetZoom();
    HRESULT SetZoom(long value, bool isAuto);
private:
    void InitDirect(QString path);
    void SearchDestDevInfo();
    QString Wchat_tToQString(wchar_t* name);

private:
    QString m_path{""};
    IAMVideoProcAmp* m_proc_amp{nullptr};
    IAMCameraControl* m_control{nullptr};
    IAMStreamConfig* m_config{nullptr};
};

#endif // UVCDEVICE_H

2、UvcDevice.cpp

#include "UvcDevice.h"
#include <uuids.h>
#include <QDebug>
UvcDevice::UvcDevice()
{
}

UvcDevice::~UvcDevice()
{
    if (m_proc_amp)
    {
        m_proc_amp->Release();
        m_proc_amp = nullptr;
    }
    if (m_control)
    {
        m_control->Release();
        m_control = nullptr;
    }
    if (m_config)
    {
        m_config->Release();
        m_config = nullptr;
    }
}

void UvcDevice::SetPath(QString path)
{
    InitDirect(path);
}

UVCParameter UvcDevice::GetZoom()
{
    UVCParameter parameter;
    if (!m_control)
        return parameter;
    HRESULT hr;
    hr = m_control->GetRange(CameraControl_Zoom, &parameter.min_val,
                             &parameter.max_val, &parameter.step, &parameter.def, &parameter.flags);
    hr = m_control->Get(CameraControl_Zoom, &parameter.val, &parameter.flags);
    return parameter;
}

HRESULT UvcDevice::SetZoom(long value, bool isAuto)
{
    if (!m_control)
        return E_HANDLE;
    long flag = isAuto ? CameraControl_Flags_Auto : CameraControl_Flags_Manual;
    return m_control->Set(CameraControl_Zoom, value, flag);
}

void UvcDevice::InitDirect(QString path)
{
    m_path = path.toLower();

    if (m_proc_amp)
    {
        m_proc_amp->Release();
        m_proc_amp = nullptr;
    }
    if (m_control)
    {
        m_control->Release();
        m_control = nullptr;
    }
    if (m_config)
    {
        m_config->Release();
        m_config = nullptr;
    }
    SearchDestDevInfo();
}

void UvcDevice::SearchDestDevInfo()
{
    if (m_path.isEmpty())
        return;
    // 创建系统设备枚举器
    ICreateDevEnum* dev_enum = nullptr;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC, IID_ICreateDevEnum, (void**)&dev_enum);

    if (FAILED(hr))
    {
        return;
    }

    IGraphBuilder* graph = nullptr;
    ICaptureGraphBuilder2* builder = nullptr;

    // Create the Filter Graph Manager.
    hr = CoCreateInstance(CLSID_FilterGraph, nullptr, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&graph);

    if (SUCCEEDED(hr))
    {
        // Create the Capture Graph Builder.
        hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, nullptr,
                              CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
                              (void**)&builder);
        if (SUCCEEDED(hr))
        {
            hr = builder->SetFiltergraph(graph);
        }
        else
        {
            return;
        }
    }
    else
    {
        return;
    }

    // 为类别创建枚举器
    IEnumMoniker* class_enum = nullptr;
    hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &class_enum, 0);

    if (hr != S_OK)
        return;

    IMoniker* moniker = nullptr;
    ULONG fetched;

    // 使用 IEnumMoniker 接口枚举所有的设备标识
    while (class_enum->Next(1, &moniker, &fetched) == S_OK)
    {
        IPropertyBag* prop_bag = nullptr;
        hr = moniker->BindToStorage(NULL, NULL, IID_IPropertyBag, (void**)&prop_bag);
        VARIANT var_name;
        VariantInit(&var_name);
        hr = prop_bag->Read(L"DevicePath", &var_name, NULL);
        WCHAR* devicePath = var_name.bstrVal;

        if (devicePath != nullptr) {
            QString dest = Wchat_tToQString(devicePath);
            qDebug()<<" dest:"<<dest;
            if (m_path.contains(dest))    // 设备匹配
            {
                IBaseFilter* src = nullptr;
                moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&src);

                // 查找 ProcAmp 接口,该接口控制亮度等相关参数
                src->QueryInterface(IID_IAMVideoProcAmp, (void**)&m_proc_amp);
                // 查找 Control 接口,该接口控制缩放等相关参数
                src->QueryInterface(IID_IAMCameraControl, (void**)&m_control);
                // 查找 Config  接口,该接口查询摄像头支持的格式
                builder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, src, IID_IAMStreamConfig, (void**)&m_config);

                src->Release();
                prop_bag->Release();
                moniker->Release();
                break;
            }
        }

        prop_bag->Release();
        moniker->Release();
    }

    class_enum->Release();
    dev_enum->Release();
    builder->Release();
    graph->Release();
}

QString UvcDevice::Wchat_tToQString(wchar_t *name)
{
    QString ret = QString((QChar*)name, wcslen(name));
    return ret;
}

三、错误解决:
错误:UvcDevice.obj : error LNK2019: 无法解析的外部符号 __imp__CoCreateInstance@20,函数 “private: void __thiscall UvcDevice::SearchDestDevInfo(void)” (?SearchDestDevInfo@UvcDevice@@AAEXXZ) 中引用了该符号
UvcDevice.obj : error LNK2019: 无法解析的外部符号 __imp__VariantInit@4,函数 “private: void __thiscall UvcDevice::SearchDestDevInfo(void)” (?SearchDestDevInfo@UvcDevice@@AAEXXZ) 中引用了该符号
debug\UvcCameraTest.exe : fatal error LNK1120: 2 个无法解析的外部命令
解决方法:在.pro中引入模块:axcontainer

QT       += core gui multimedia axcontainer
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
获取设置UVC相机属性可以使用Qt和Media Foundation框架。以下是一些步骤: 1. 首先,需要使用Media Foundation框架来获取UVC相机的属性。在此之前,需要确保已经正确安装了Media Foundation SDK和UVC相机驱动程序。 2. 使用Media Foundation框架的IMFActivate接口来获取UVC相机设备的属性。可以使用以下代码: ``` IMFAttributes* pAttributes = NULL; IMFActivate** ppDevices = NULL; // Create an attribute store to specify the enumeration parameters. HRESULT hr = MFCreateAttributes(&pAttributes, 1); if (SUCCEEDED(hr)) { // Specify the enumeration parameter. hr = pAttributes->SetGUID( MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID ); } if (SUCCEEDED(hr)) { // Enumerate the devices. UINT32 count; hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count); } if (SUCCEEDED(hr)) { // Iterate through the devices and get the properties. for (UINT32 i = 0; i < count; i++) { IMFAttributes* pDeviceAttributes = NULL; hr = ppDevices[i]->GetAttributes(&pDeviceAttributes); if (SUCCEEDED(hr)) { // Get the device name. WCHAR* pName = NULL; UINT32 cchName; hr = ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &pName, &cchName); if (SUCCEEDED(hr)) { wprintf(L"Device name: %s\n", pName); CoTaskMemFree(pName); } // Get the device ID. WCHAR* pId = NULL; UINT32 cchId; hr = ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &pId, &cchId); if (SUCCEEDED(hr)) { wprintf(L"Device ID: %s\n", pId); CoTaskMemFree(pId); } // Get the device attributes. GUID subtype; UINT32 width, height, fps; hr = pDeviceAttributes->GetGUID(MF_MT_SUBTYPE, &subtype); if (SUCCEEDED(hr)) { hr = MFGetAttributeSize(pDeviceAttributes, MF_MT_FRAME_SIZE, &width, &height); } if (SUCCEEDED(hr)) { hr = MFGetAttributeRatio(pDeviceAttributes, MF_MT_FRAME_RATE, &fps, 1); } if (SUCCEEDED(hr)) { wprintf(L"Video format: %s, %dx%d, %dfps\n", GetSubtypeName(subtype), width, height, fps); } pDeviceAttributes->Release(); } ppDevices[i]->Release(); } CoTaskMemFree(ppDevices); } pAttributes->Release(); ``` 3. 上面的代码将枚举UVC相机设备并获取它们的属性,包括设备名称、设备ID和视频格式。可以根据需要设置其他属性,例如曝光时间、增益等。可以使用以下代码设置相机属性: ``` IMFMediaSource* pSource = NULL; IMFAttributes* pAttributes = NULL; // Create the media source from the device ID. hr = MFCreateDeviceSource(pId, &pAttributes, &pSource); if (SUCCEEDED(hr)) { // Set the exposure time. hr = pAttributes->SetUINT64(MF_VIDCAP_CAMERACONTROL_EXPOSURE, exposureTime); } if (SUCCEEDED(hr)) { // Set the gain. hr = pAttributes->SetUINT64(MF_VIDCAP_CAMERACONTROL_GAIN, gainValue); } if (SUCCEEDED(hr)) { // Set the white balance. hr = pAttributes->SetUINT32(MF_VIDCAP_CAMERACONTROL_WHITEBALANCE, whiteBalanceValue); } // Release the media source and attributes. pSource->Release(); pAttributes->Release(); ``` 4. 上面的代码将设置UVC相机的曝光时间、增益和白平衡。可以根据需要设置其他属性。 希望这些代码可以帮助你获取设置UVC相机属性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值