Last active
January 18, 2021 04:20
-
-
Save wrongbranch/88ea47bffe7b5ebb4206ae0572114080 to your computer and use it in GitHub Desktop.
DirectShow_Graph_trap_OpenCV.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
DirectShow_Graph_trap_OpenCV.cpp | |
Camera -> Render and Grab (DirectShow) -> OpenCV | |
ref | |
OpenCV (old) DirectShow (old) 2008.12.15 Soaphacker | |
http://hisoap.jugem.jp/?eid=141 | |
cv.lib cxcore.lib cvaux.lib highgui.lib strmiids.lib | |
DirectX DirectShow (old) | |
https://blog.zamuu.net/2011/0322/visualstudio2008-vc-directshow/ | |
dxerr.lib dxgui.lib d3dx9.lib d3dx10.lib d3d9.lib | |
winmm.lib strmiids.lib strmbase.lib | |
rewrite for cv::Mat | |
test with OpenCV 3.4.12 https://github.com/opencv/opencv/releases/tag/3.4.12 | |
x64/vc15/bin | |
opencv_world3412.dll | |
opencv_ffmpeg3412_64.dll | |
use Microsoft Visual Studio 2017 | |
x64 compiler/linker | |
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\cl.exe" | |
-source-charset:utf-8 -execution-charset:utf-8 | |
-EHsc -FeDirectShow_Graph_trap_OpenCV.exe DirectShow_Graph_trap_OpenCV.cpp | |
-I. | |
-IC:\OpenCV3\include | |
-link | |
/LIBPATH:C:\OpenCV3\x64\vc15\lib | |
/LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\lib\x64" | |
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64" | |
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\um\x64" | |
opencv_world3412.lib ole32.lib strmiids.lib | |
del .\DirectShow_Graph_trap_OpenCV.obj | |
DirectShow_Graph_trap_OpenCV | |
*/ | |
#define UNICODE | |
#define _UNICODE | |
#include <wchar.h> | |
#define WIN32_LEAN_AND_MEAN | |
#define _WIN32_DCOM | |
#define _CRT_SECURE_NO_DEPRECATE | |
#include <windows.h> | |
#include <dshow.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
// download qedit.h and edit it | |
#include <qedit.h> // CLSID_SampleGrabber ISampleGrabber IID_ISampleGrabber | |
// use CV_PI instead of M_PI | |
// #define _USE_MATH_DEFINES | |
#include <opencv2/opencv.hpp> | |
int main(int ac, char **av) | |
{ | |
HRESULT hr = CoInitialize(NULL); | |
if(FAILED(hr)){ | |
fprintf(stderr, "CoInitialize Failed\n"); | |
return 1; | |
} | |
ICreateDevEnum *pDevEnum = NULL; | |
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, | |
IID_ICreateDevEnum, (void **)&pDevEnum); | |
IEnumMoniker *pClassEnum = NULL; | |
pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0); | |
if(!pClassEnum){ | |
fprintf(stderr, "Device does not exist\n"); | |
pDevEnum->Release(); | |
CoUninitialize(); | |
return 2; | |
} | |
// find Nth filter | |
IBaseFilter *pbf = NULL; | |
for(int c = 0; c < 3; ++c){ | |
if(pbf){ pbf->Release(); pbf = NULL; } | |
ULONG cFetched; | |
IMoniker *pMoniker = NULL; | |
if(pClassEnum->Next(1, &pMoniker, &cFetched) == S_OK){ | |
pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pbf); | |
pMoniker->Release(); | |
} | |
} | |
pClassEnum->Release(); | |
pDevEnum->Release(); | |
if(!pbf){ | |
fprintf(stderr, "Video Capture Filter not found\n"); | |
CoUninitialize(); | |
return 3; | |
} | |
IGraphBuilder *pGraph = NULL; | |
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, | |
IID_IGraphBuilder, (void **)&pGraph); | |
pGraph->AddFilter(pbf, L"Video Capture"); | |
IBaseFilter *pF = NULL; | |
CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, | |
IID_IBaseFilter, (LPVOID *)&pF); | |
ISampleGrabber *pGrab = NULL; | |
pF->QueryInterface(IID_ISampleGrabber, (void **)&pGrab); | |
AM_MEDIA_TYPE amt; | |
ZeroMemory(&amt, sizeof(AM_MEDIA_TYPE)); | |
amt.majortype = MEDIATYPE_Video; | |
amt.subtype = MEDIASUBTYPE_RGB24; // check | |
amt.formattype = FORMAT_VideoInfo; | |
pGrab->SetMediaType(&amt); | |
pGraph->AddFilter(pF, L"Grabber"); | |
ICaptureGraphBuilder2 *pCapture = NULL; | |
CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, | |
IID_ICaptureGraphBuilder2, (void **)&pCapture); | |
pCapture->SetFiltergraph(pGraph); | |
pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, | |
pbf, NULL, pF); | |
IMediaControl *pMC = NULL; | |
pGraph->QueryInterface(IID_IMediaControl, (LPVOID *)&pMC); | |
pMC->Run(); // start render | |
pGrab->SetBufferSamples(TRUE); // Grab | |
pGrab->GetConnectedMediaType(&amt); | |
fprintf(stdout, "amt.lSampleSize = %dbytes\n", amt.lSampleSize); | |
VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER *)amt.pbFormat; | |
BITMAPINFO bmi; | |
ZeroMemory(&bmi, sizeof(bmi)); | |
BITMAPINFOHEADER *pH = &bmi.bmiHeader; | |
CopyMemory(pH, &pVIH->bmiHeader, sizeof(BITMAPINFOHEADER)); | |
fprintf(stdout, "%dx%d %dbits\n", pH->biWidth, pH->biHeight, pH->biBitCount); | |
// OpenCV from here | |
// only 24bit support | |
cv::namedWindow("Src", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO); | |
cv::Mat frm(pH->biHeight, pH->biWidth, CV_8UC3); | |
while(1){ | |
hr = pGrab->GetCurrentBuffer((long *)&pH->biSizeImage, (long *)frm.data); | |
if(FAILED(hr)){ if(cv::waitKey(50) == 'q') break; else continue; } | |
#if 0 | |
// im->origin 0: left-top, 1: left-bottom | |
IplImage *im = cvCreateImage(cvSize(frm.cols, frm.rows), IPL_DEPTH_8U, 3); | |
if(!im->origin) cv::flip(frm, frm, 0); // reverse top <-> bottom | |
cvReleaseImage(&im); | |
#else | |
cv::flip(frm, frm, 0); // reverse top <-> bottom | |
#endif | |
cv::imshow("Src", frm); | |
int k = cv::waitKey(10); | |
if(k == 'q') break; | |
switch(k){ | |
default: break; // skip | |
} | |
} | |
cv::destroyAllWindows(); | |
// OpenCV end | |
pMC->Release(); // Filter Graph | |
pCapture->Release(); // Capture Graph | |
pGrab->Release(); | |
pF->Release(); // Sample Grabber | |
pGraph->Release(); | |
pbf->Release(); // Capture Filter | |
CoUninitialize(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment