在 Windows 中从 USB 摄像头拍摄高分辨率照片 (C++)

rad*_*oid 6 c++ camera directshow photo wmf

我正在开发一个 C++ 应用程序,它应该使用 USB 相机来捕获高分辨率照片。它应该与 Windows 10 中的相机应用程序具有相同的行为。我正在尝试使用 DirectShow 来执行此操作。现在我只能拍摄延迟的高分辨率照片或及时拍摄但分辨率较低的照片。另外,我对 MS 文档感到非常困惑,很多东西都已被弃用,并且没有提到什么可以替代它们。我将描述我绝望的步骤,等待有人能够向我展示一条道路。

让我们从头开始...

对 Window 中的视频捕获一无所知,我首先搜索合适的库。经过一番谷歌搜索后,我发现 Windows 中有四个用于捕获视频的主要库。

  1. Windows 视频
  2. 直播
  3. Windows媒体基金会
  4. 开放式计算机视觉

我们来观察一下:

  1. Video for Windows
    不幸的是,该库被标记为已弃用,但它似乎仍然有效。我写了“不幸的是”,因为我认为这是唯一易于使用的。查看来自摄像机的视频只需要几行代码。我唯一想念的是“TakePhoto”功能。您可以使用 VFW 将视频或单个帧捕获为 avi 文件。或者我错过了什么?

  2. DirectShow
    这是一个复杂得多的库。您需要数百行代码才能查看视频预览。但您可以在 MS Docs 上获取此代码。好的,现在我有了视频预览,我只需要拍照。人们会认为这应该只是一个函数调用。但功能在哪里呢?我没有找到。

您可以简单地使用GetCurrentImagefrom IVMRWindowlessControl,但这仅需要低分辨率预览中的一帧。如果您设置较高的预览分辨率,视频会不流畅。

我可以实现的最佳方法来自一篇名为“从静态图像 Pin 捕获图像”的文章,此处提供https://learn.microsoft.com/en-us/windows/desktop/directshow/capturing-an-image-from- a-静态图像-pin。当我找到这个网站时,我以为我赢了,我的任务几乎完成了。但事实并非如此。

本文给您的第一个建议是不要使用它:“从设备获取静态图像的推荐方法是使用 Windows Image Acquisition (WIA) API。有关详细信息,请参阅平台中的“Windows Image Acquisition” SDK 文档。但是,您也可以使用 DirectShow 来捕获图像。” 我尝试探索 WIA。但这在 Vista 上就不起作用了。我继续研究这篇文章。
一切似乎都很清楚,但您需要实现继承ISampleGrabberCB标记为已弃用的类https://learn.microsoft.com/en-us/windows/desktop/directshow/isamplegrabbercb。为什么????哪里可以找到替代方案?
我在这里找到了一个可接受的解决方案https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/2ab5c212-5824-419d-b5d9-7f5db82f57cd/qedith-missing-in-current-windows-sdk-v70?论坛=windowsdirectshowdevelopment。您需要添加来自older SDK 的头文件。(顺便说一句,这是一个近十年前的建议。)在我使用此标头编译应用程序后,我能够读取高分辨率图片,但我需要等待几秒钟,这是不可接受的。我知道问题不在相机中,因为它在相机应用程序中工作。此外,图像是通过函数SampleCB而不是函数获得的BufferCB,并且采用某种奇怪的格式。我可以将其另存为jpg,但压缩程度不够。

  1. Windows Media Foundation
    我认为 MS 不喜欢程序员,这就是它发布 WMF 的原因。我一点都没懂。我找到了这个教程https://www.dreamincode.net/forums/topic/347938-a-new-webcam-api-tutorial-in-c-for-windows/。它可以工作,但它只存储预览中的一帧,这不是我想要的。
    接下来我探索了 MS Docs 上的一些 WMF 接口。IMFCapturePhotoSink 接口应该完成这些工作。但如何实施呢。文档没有用。

  2. OpenCV
    在我的研究过程中我也发现了这个库。但我再次无法拍摄高分辨率照片。它仅存储预览中的一帧。

有人可以告诉我我应该关注什么吗?我相信这不会那么困难。网络摄像头的应用程序有数十个和数百个。其他程序员如何实现它们?我怎么了?我想找到一种简单的方法来完成一项简单的任务。非常感谢您的帮助。

Evg*_*uda 0

您的问题与主题无关 - 该问题必须与代码相关 - 但我多年前遇到过类似的问题,并且我找到了解决方案:

DirectShow已声明在 Windows 10 中已弃用,并且在支持 USB 网络摄像头方面存在问题。在 Windows 10 中,有 USB 视频类,仅受 Media Foundation 支持。

因此,我围绕 Media Foundation 代码编写了一个简单的 C++ 包装器,该包装器简化了使用 Media Foundation 从 Windows 7 和 8 上的网络摄像头捕获视频的原始图像的获取

此外,还有项目CaptureManager SDK - 它是DLL COM组件,具有简单的接口、强大的功能以及许多C++、Python、C#、Java上的演示程序。