我正在开发一个C ++应用程序,该应用程序应使用USB相机来捕获高分辨率照片。它的行为应与Windows 10中的“相机”应用程序相同。我正在尝试使用DirectShow。现在,我只能拍摄延迟的高分辨率照片,或者只能及时拍摄但分辨率低的照片。另外,我对MS文档感到非常困惑,不赞成使用许多功能,没有地方提到用什么代替它们。我将描述我绝望的步骤,等待有可能向我展示方法的人。
让我们从头开始...
对于在Window中捕获视频一无所知,我从搜索合适的库开始。经过一番谷歌搜索后,我发现有四个用于在Windows中捕获视频的主要库。 1 / Windows视频 2 / DirectShow 3 / Windows Media基金会 4 / OpenCV
让我们观察一下: 1 / Windows视频 不幸的是,该库已被标记为已弃用,但似乎仍然可以使用。我写了“不幸的是”,因为我认为这是唯一易于使用的。从摄像机观看视频仅需几行代码。我唯一想念的是“ TakePhoto”功能。您可以使用VFW将视频或单个帧捕获到avi文件。还是我错过了什么?
2 / DirectShow 这个库要复杂得多。您需要数百行代码才能查看视频预览。但是您可以在MS Docs上获得此代码。好的,现在我有了视频预览,我只需要拍照。有人希望这应该只是一个函数调用。但是功能在哪里。我没有找到。
您可以简单地使用IVMRWindowlessControl中的GetCurrentImage,但这仅以低分辨率从预览中获取一帧。如果您为预览设置更高的分辨率,则视频不流畅。
我可以实现的最佳方法是从https://docs.microsoft.com/en-us/windows/desktop/directshow/capturing-an-image-from-a-still-image-pin提供的一篇文章从静止图像引脚捕获图像。当我找到这个站点时,我以为我赢了,我的任务几乎完成了。但这不是。
本文为您提供的第一个建议是不要使用它:“从设备获取静止图像的推荐方法是使用Windows Image Acquisition(WIA)API。有关更多信息,请参见“ Windows Image Acquisition”。在Platform SDK文档中。但是,您也可以使用DirectShow捕获图像。”我试图探索WIA。但这已停止在Vista上运行。我继续研究这篇文章。 一切似乎都很清楚,但是您需要实现继承自ISampleGrabberCB的类,该类在此处https://docs.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?forum=windowsdirectshowdevelopment找到了可接受的解决方案。您需要从旧的SDK添加头文件。 (顺便说一句,这是将近十年的建议。)在使用此标头编译应用程序之后,我能够读取高分辨率图片,但是我需要等待几秒钟,这是不可接受的。我知道问题不在相机中,因为它可以在相机应用程序中使用。此外,图像是通过函数SampleCB而不是BufferCB获得的,并且格式有些奇怪。我可以将其另存为jpg,但压缩程度不足。
3 / 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界面应该做的事情。但是如何实施。该文档是无用的。
4 / OpenCV 在研究过程中,我也找到了这个库。但是我又不能拍高分辨率的照片。它仅存储预览中的一帧。
有人可以告诉我我应该关注什么吗?我相信这不会那么困难。网络摄像头有成千上万的应用程序。其他程序员如何实现它们?我怎么了我想找到一种简单的方法来执行简单的任务。非常感谢您的帮助。
答案 0 :(得分:0)
您的问题与该主题无关-该问题必须与代码相关-但是很多年前,我遇到了类似的问题,并且找到了解决方案:DirectShow被声明为Windows 10弃用,并且存在问题支持USB网络摄像头-在Windows 10中,只有Media Foundation支持USB Video Class。因此,我围绕Media Foundation代码编写了一个简单的C ++包装器,该包装器简化了原始图像Capturing Video from Web-camera on Windows 7 and 8 by using Media Foundation的获取 另外,还有一个项目CaptureManager SDK-它是DLL COM组件,具有简单的界面,强大的功能以及许多基于C ++,Python,C#,Java的演示程序。
答案 1 :(得分:0)
感谢叶夫根尼。
重述:
1 /下载CaptureEngine video capture sample
2 /编辑CaptureManager :: TakePhoto方法。在“ CreatePhotoMediaType(pMediaType,&pMediaType2);”之前添加代码以查找最高分辨率的媒体类型。线
用于将照片流设置为最高分辨率的附加代码:
DWORD dwMediaTypeIndex = 0;
UINT32 maxSize = 0;
DWORD maxSizeIndex = 0;
while (1) {
IMFMediaType* pMediaType = NULL;
hr = pSource->GetAvailableDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, dwMediaTypeIndex, &pMediaType);
if (hr == MF_E_NO_MORE_TYPES)
break;
UINT32 w, h;
MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &w, &h);
UINT32 size = w * h;
if (size > maxSize) {
maxSize = size;
maxSizeIndex = dwMediaTypeIndex;
}
SafeRelease(&pMediaType);
dwMediaTypeIndex++;
}
SafeRelease(&pMediaType);
pSource->GetAvailableDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, maxSizeIndex, &pMediaType);