MFC 调用UVC相机
时间: 2023-09-14 07:09:18 浏览: 181
要在MFC应用程序中调用UVC相机,需要使用UVC库提供的API。以下是一个简单的MFC应用程序示例,演示如何使用UVC库访问USB摄像头:
```cpp
#include "stdafx.h"
#include <dshow.h>
#include <strmif.h>
#include <opencv2/opencv.hpp>
#pragma comment(lib, "strmiids.lib")
void CMyAppDlg::OnBnClickedButtonStart()
{
HRESULT hr;
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
IBaseFilter *pSrc = NULL;
ICaptureGraphBuilder2 *pBuild = NULL;
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
IVideoWindow *pVW = NULL;
IVMRWindowlessControl *pWC = NULL;
cv::Mat frame;
cv::VideoCapture cap;
// Initialize COM
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(hr)) return;
// Create the system device enumerator
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pDevEnum);
if (FAILED(hr)) goto done;
// Create an enumerator for the video capture devices
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
if (hr == S_OK)
{
// Use the first video capture device on the device list
hr = pEnum->Next(1, &pMoniker, NULL);
if (hr == S_OK)
{
// Bind the selected video capture device to a filter object
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pSrc);
if (FAILED(hr)) goto done;
// Create the capture graph builder
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2, (void**)&pBuild);
if (FAILED(hr)) goto done;
// Create the filter graph manager
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void**)&pGraph);
if (FAILED(hr)) goto done;
// Attach the filter graph manager to the capture graph builder
hr = pBuild->SetFiltergraph(pGraph);
if (FAILED(hr)) goto done;
// Add the video capture device filter to the filter graph manager
hr = pGraph->AddFilter(pSrc, L"Video Capture");
if (FAILED(hr)) goto done;
// Render the video stream from the video capture device filter
hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pSrc, NULL, NULL);
if (FAILED(hr)) goto done;
// Get the media control interface from the filter graph manager
hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
if (FAILED(hr)) goto done;
// Get the media event interface from the filter graph manager
hr = pGraph->QueryInterface(IID_IMediaEvent, (void**)&pEvent);
if (FAILED(hr)) goto done;
// Get the video window interface from the filter graph manager
hr = pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVW);
if (FAILED(hr)) goto done;
// Get the VMR windowless control interface from the filter graph manager
hr = pGraph->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWC);
if (FAILED(hr)) goto done;
// Set the video window style and position
pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
pVW->put_Owner((OAHWND)m_hWnd);
pVW->put_MessageDrain((OAHWND)m_hWnd);
pVW->SetWindowPosition(0, 0, 640, 480);
// Set the VMR windowless control aspect ratio mode to letterbox
pWC->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX);
pWC->SetVideoPosition(NULL, &RECT{ 0, 0, 640, 480 });
// Start the capture graph
hr = pControl->Run();
if (FAILED(hr)) goto done;
// Start OpenCV video capture
cap.open(0);
if (!cap.isOpened()) goto done;
// Main loop
for (;;)
{
// Get the next video frame from the capture device
hr = pEvent->WaitForCompletion(INFINITE, NULL);
if (hr != S_OK) break;
// Retrieve the video frame from the capture device
cap >> frame;
// Display the video frame in the video window
cv::imshow("Video", frame);
cv::waitKey(1);
// Release the video frame
frame.release();
}
}
}
done:
// Cleanup
if (pSrc) pSrc->Release();
if (pBuild) pBuild->Release();
if (pGraph) pGraph->Release();
if (pControl) pControl->Release();
if (pEvent) pEvent->Release();
if (pVW) pVW->Release();
if (pWC) pWC->Release();
if (pMoniker) pMoniker->Release();
if (pEnum) pEnum->Release();
if (pDevEnum) pDevEnum->Release();
CoUninitialize();
}
```
在这个示例中,我们使用了DirectShow API来访问UVC相机,并使用OpenCV来显示视频流。具体来说,我们首先使用ICreateDevEnum接口枚举可用的视频捕获设备,然后使用IMoniker接口获取所选设备的过滤器对象。接下来,我们使用ICaptureGraphBuilder2接口创建捕获图形生成器,使用IGraphBuilder接口创建过滤器图形管理器,并将其附加到捕获图形生成器上。我们将视频捕获设备过滤器添加到过滤器图形管理器中,并使用pBuild->RenderStream方法将视频流从过滤器输出端呈现到过滤器输入端。最后,我们使用IMediaControl接口启动过滤器图形管理器,使用OpenCV的cv::VideoCapture类获取视频帧,并使用cv::imshow方法显示视频帧。
阅读全文