首页 > 解决方案 > 以毫秒为单位的媒体基础曝光

问题描述

在我提出问题之前,我需要说明我主要是一名 Linux C++ 开发人员,并且没有太多编写 Windows 应用程序的经验。我使用 g++ 而不是 Microsoft 编译器编译所有代码。

背景

一段时间以来,我一直致力于支持各种专业相机的科学成像应用程序。这些相机中的大多数都有制造商提供的 SDK,这使得开发更加容易。但是,我的应用程序支持的一些相机是标准 UVC 相机。直到最近,这个应用程序一直专门用于 Linux,但现在正在移植到 macOS 和 Windows。

  1. Linux 端口通过 Video4Linux 实现了 UVC 支持,并且运行得非常好。
  2. macOS 端口通过 libuvc ( https://github.com/libuvc/libuvc ) 实现 UVC 支持并且运行良好

问题:Windows UVC 支持

我在 Windows 上实现 UVC 相机时遇到问题。我编写了 DirectShow 和 Media Framework 处理器,它们运行良好,可以控制增益、亮度、对比度等参数,以及 V4L2,这正是我所需要的。但是,当我尝试实施曝光控制时,问题就出现了。

如果我使用记录曝光范围为 1 毫秒到 1000 毫秒的特定 UVC 相机,那么我可以通过使用 V4L2_CID_EXPOSURE_ABSOLUTE 来使用 Video4Linux 的完整曝光范围。当应用新的曝光时,我看到输出图像的线性变化很好。在 macOS 上使用 libuvc 时,我可以观察到相同的情况。

在 Windows 上使用 DirectShow 或 Media Foundation 上的相同相机时,曝光范围非常不同。我使用以下代码查询曝光控制的范围:

HRESULT hr;
IAMCameraControl *cam_ctrl = NULL;

long lmin, lmax, lstep, ldft, lcap;

hr = m_imf_media_source->QueryInterface(IID_IAMCameraControl, (void**) &cam_ctrl);
if (FAILED(hr))
{
    throw_error(hr);
}
hr = cam_ctrl->GetRange(CameraControl_Exposure, &lmin, &lmax, &lstep, &ldft, &lcap);

if (FAILED(hr))
{
    if (hr == E_PROP_ID_UNSUPPORTED)
    {
        *min = 0;
        *max = 0;
        *value = 0;
        return false;
    }
    else
    {
        throw_error(hr);
    }
}
*min = static_cast<int>(lmin);
*max = static_cast<int>(lmax);
*value = static_cast<int>(ldft);

return true;

如文档所述,从proc_amp->GetRange发现的值不是实时单位。例如,这些值为 -11 到 -3,对于某些支持大于 1000 毫秒曝光的 UVC 相机,这些值为正值。当我将曝光应用于流时,步骤非常粗糙。如前所述,Linux 下这个特定相机的曝光步骤是线性的,有数百个步骤。在 Windows 中只有大约 14 个。

我的主要问题是:可以在 DirectShow 或 Media Foundations 中使用具有实时单元的 UVC 相机,如果是这样,这是如何完成的?如果有人有任何想法,我很乐意考虑另一种方法。遗憾的是,这种粗略的曝光步骤是不可接受的。

我知道在 Windows 上支持 libuvc,但它需要安装特定的驱动程序,这是我真的不希望我的用户做的事情。

非常感谢所有帮助。

阿曼达。

标签: c++windowsdirectshowms-media-foundationuvc

解决方案


推荐阅读