Hallo Leute,
ich versuche derzeit eine Programm zu schreiben, welches meine Webcam initialisiert/connected und Bilder von der Webcam abholt.
Zuerst habe ich OpenCV versucht - nach einer halben Stunde lief alles einwandfrei und ich konnte mir das Livebild ansehen.
Leider habe ich aber keine Googletreffer oder ähnliches finden können, das es mir erlaubt mit OpenCV Parameter der Webcam zu ändern wie zum Beispiel den (Hardware-)Weißabgleich abzuschalten.
Daher bin ich dann auf DirectShow umgeschwenkt und mich traf der Knüppel auf den Kopf.
Ein kleines Snippet im Internet hat mir den Einstieg erleichtert - jedoch fehlte mir die streams.h (um die GUIDs auflösen zu können wie z.B. CLSID_VideoInputDeviceCategory), welche nur mit der Windows SDK geliefert wird.
Windows SDK gezogen und installiert
Weiterhin hatte ich keine sal.h, welche aus dem VB kommt
VB gezogen und installiert.
Sooo, nun steh ich da mit meinem Snippet und MinGW(3.15.2)/GCC(4.4.0) und der Compiler meckert nur rum, das er die Abhängigkeiten nicht auflösen kann:
Damit GCC die <streams.h> finden kann habe ich den INCLUDEPATH wie folgt gesetzt:
WINSTREAM = $$quote(C:\Programme\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses)
INCLUDEPATH = $${WINSTREAM}
Jetzt nörgelt er rum, dass er die Abhängigkeiten wie z.B. die intsafe.h nicht auflösen kann, weil sie woanders liegt: C:\Programme\Microsoft SDKs\Windows\v7.1\Include
Um das zu lösen habe ich dem .pro-File auch diesen Pfad übergeben und noch einen weiteren:
WINSTREAM = $$quote(C:\Programme\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses)
WINSDK = $$quote(C:\Programme\Microsoft SDKs\Windows\v7.1\Include)
VBSDK = $$quote(C:\Programme\Microsoft Visual Studio 10.0\VC\Include)
INCLUDEPATH = $${WINSTREAM} \
$${WINSDK} \
$${VBSDK}
Nach dem nicht erfolgreichen Kompilieren, springen mich ca. 3000 neue Fehler an.
Beispielsweise: C:/logitech_cam/../Programme/Microsoft SDKs/Windows/v7.1/Include/winnt.h:1202: error: pasting "(" and "__drv_nop" does not give a valid preprocessing token
oder C:/logitech_cam/../Programme/Microsoft SDKs/Windows/v7.1/Include/oleauto.h:546: error: expected primary-expression before '*' token
Was mache ich falsch? Meine Idee ist, den DEPENDPATH dafür zu nutzen, der aber bislang keinerlei Änderungen hervorgerufen hat.
Andere Vermutung wäre, dass sich VB-Source und Win SDK sich einfach nicht mit MinGW vertragen.
Hoffentlich kennt sich jemand mit QT in Verbindung mit DirectShow für Webcams aus.
Grüße Pixtar
Qt + Win SDK + DirectShow
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Re: Qt + Win SDK + DirectShow
Soweit ich weiß kann MinGW keine WinAPI-Header, welche für MSVC ausgelegt sind, verarbeiten.
Aber MinGW bringt eigene WinAPI - Header mit bzw. sind im Netz verfügbar (z.B. auf der MinGW - Projekthomepage)
Aber MinGW bringt eigene WinAPI - Header mit bzw. sind im Netz verfügbar (z.B. auf der MinGW - Projekthomepage)
MfG Christian
'Funktioniert nicht' ist keine Fehlerbeschreibung
'Funktioniert nicht' ist keine Fehlerbeschreibung
Re: Qt + Win SDK + DirectShow
Danke Christian für den Hinweis.
Das ist doch schon einmal eine neue Richtung die ich einschlagen kann. Werde dahingehend mal weitersuchen.
Das ist doch schon einmal eine neue Richtung die ich einschlagen kann. Werde dahingehend mal weitersuchen.
Re: Qt + Win SDK + DirectShow
Bin nun auf VisualStudio umgestiegen und nach einigen Kämpfen mit den Libraries kann ich nun eigentlich jede OEM-Webcam ansprechen.
Wer also Bandwurm-Code zum Testen seiner Webcam benutzen will, here it comes as console program: (no header-file needed)
[Includes:Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses; Libraries: Microsoft SDKs\Windows\v7.1\Lib]
<webcam.cpp>
Wer also Bandwurm-Code zum Testen seiner Webcam benutzen will, here it comes as console program: (no header-file needed)
[Includes:Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses; Libraries: Microsoft SDKs\Windows\v7.1\Lib]
<webcam.cpp>
Code: Alles auswählen
#pragma once
#pragma comment(lib, "strmiids")
#pragma comment(lib, "strmbase") //must be created out of "directshow\baseclasses"-folder and copied to "\Lib"-folder
#pragma comment(lib, "Rpcrt4")
#include <windows.h>
#include <cstring>
#include <tchar.h>
#include <streams.h>
#include <stdio.h>
#include <comdef.h>
#include <conio.h>
#include <dshow.h>
#include <vector>
#include <iostream>
using namespace std;
GUID mediaSubtypes[30];
int main(){
mediaSubtypes[0] = MEDIASUBTYPE_CLPL;
mediaSubtypes[1] = MEDIASUBTYPE_YUYV;
mediaSubtypes[2] = MEDIASUBTYPE_IYUV;
mediaSubtypes[3] = MEDIASUBTYPE_YVU9;
mediaSubtypes[4] = MEDIASUBTYPE_Y411;
mediaSubtypes[5] = MEDIASUBTYPE_Y41P;
mediaSubtypes[6] = MEDIASUBTYPE_YUY2;
mediaSubtypes[7] = MEDIASUBTYPE_YVYU;
mediaSubtypes[8] = MEDIASUBTYPE_UYVY;
mediaSubtypes[9] = MEDIASUBTYPE_Y211;
mediaSubtypes[10] = MEDIASUBTYPE_CLJR;
mediaSubtypes[11] = MEDIASUBTYPE_IF09;
mediaSubtypes[12] = MEDIASUBTYPE_CPLA;
mediaSubtypes[13] = MEDIASUBTYPE_MJPG;
mediaSubtypes[14] = MEDIASUBTYPE_TVMJ;
mediaSubtypes[15] = MEDIASUBTYPE_WAKE;
mediaSubtypes[16] = MEDIASUBTYPE_CFCC;
mediaSubtypes[17] = MEDIASUBTYPE_IJPG;
mediaSubtypes[18] = MEDIASUBTYPE_Plum;
mediaSubtypes[19] = MEDIASUBTYPE_DVCS;
mediaSubtypes[20] = MEDIASUBTYPE_H264;
mediaSubtypes[21] = MEDIASUBTYPE_DVSD;
mediaSubtypes[22] = MEDIASUBTYPE_MDVF;
mediaSubtypes[23] = MEDIASUBTYPE_RGB1;
mediaSubtypes[24] = MEDIASUBTYPE_RGB4;
mediaSubtypes[25] = MEDIASUBTYPE_RGB8;
mediaSubtypes[26] = MEDIASUBTYPE_RGB565;
mediaSubtypes[27] = MEDIASUBTYPE_RGB555;
mediaSubtypes[28] = MEDIASUBTYPE_RGB24;
mediaSubtypes[29] = MEDIASUBTYPE_RGB32;
string mediaSubtypesStr[30] = {"CLPL","YUYV","IYUV","YVU9","Y411","Y41P","YUY2","YVYU","UYVY","Y211","CLJR","IF09","CPLA","MJPG","TVMJ","WAKE","CFCC","IJPG","Plum","DVCS","H264","DVSD","MDVF","RGB1","RGB4","RGB8","RGB565","RGB555","RGB24","RGB32"};
system("cls");
printf("\n\nUSB-Videodevice and Capturing\n_______________________________________________________\n\n");
// for playing
IGraphBuilder *pGraphBuilder;
ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
IMediaControl *pMediaControl;
IBaseFilter *pDeviceFilter = NULL;
// to select a video input device
ICreateDevEnum *pCreateDevEnum = NULL;
IEnumMoniker *pEnumMoniker = NULL;
IMoniker *pMoniker = NULL;
ULONG nFetched = 0;
// initialize COM
CoInitialize(NULL);
//
// selecting a device
//
// Create CreateDevEnum to list device
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum);
// Create EnumMoniker to list VideoInputDevice
pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0);
if (pEnumMoniker == NULL) {
// this will be shown if there is no capture device
printf("No Device Found!\n");
return 0;
}
// reset EnumMoniker
pEnumMoniker->Reset();
// get each Moniker
while (pEnumMoniker->Next(1, &pMoniker, &nFetched) == S_OK) {
IPropertyBag *pPropertyBag;
TCHAR devname[256];
// bind to IPropertyBag
pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropertyBag);
VARIANT var;
// get FriendlyName
var.vt = VT_BSTR;
pPropertyBag->Read(L"FriendlyName", &var, 0);
WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, devname, sizeof(devname), 0, 0);
VariantClear(&var);
printf("Devicename: %s\n", devname);
printf("Do you want to select this device? [y] or [n]\n>> ");
int ch = getchar();
// you can start playing by 'y' + return key
// if you press the other key, it will not be played.
if (ch == 'y') {
// Bind Monkier to Filter
pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pDeviceFilter );
}
printf("_______________________________________________________\n\n");
// release
pMoniker->Release();
pPropertyBag->Release();
// go out of loop if getchar() returns 'y'
if (pDeviceFilter != NULL) { break; }
}
if (pDeviceFilter != NULL) {
// create FilterGraph
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (LPVOID *)&pGraphBuilder);
// create CaptureGraphBuilder2
CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (LPVOID *)&pCaptureGraphBuilder2);
// Initialize the IAMStream structure
HRESULT hr = CoInitialize(0);
IAMStreamConfig *pConfig = NULL;
hr = pCaptureGraphBuilder2->FindInterface(&PIN_CATEGORY_CAPTURE, 0, pDeviceFilter, IID_IAMStreamConfig, (void**)&pConfig);
int iCount = 0, iSize = 0;
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
// Check the size to make sure we pass in the correct structure.
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)){
// Use the video capabilities structure.
printf("\n\nPossible camera resolution\n");
printf("_______________________________________________________\n");
for (int iFormat = 0; iFormat < iCount; iFormat++){
VIDEO_STREAM_CONFIG_CAPS scc;
AM_MEDIA_TYPE *pmtConfig;
hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
if (SUCCEEDED(hr)){
/* Examine the format, and possibly use it. */
if(pmtConfig->majortype == MEDIATYPE_Video){
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig->pbFormat;
// pVih contains the detailed format information.
LONG lWidth = pVih->bmiHeader.biWidth;
LONG lHeight = pVih->bmiHeader.biHeight;
/* Run through all possible formats of the device and list them */
if(lWidth!=0){
printf("\n%i. Format\n\tWidth=%i\tHeight=%i\n\tType=%s\t", iFormat+1, lWidth, lHeight, "Video");
int k=0;
while(mediaSubtypes[k]!=pmtConfig->subtype)
k++;
char * buffer = new char[mediaSubtypesStr[k].length()];
strcpy(buffer,mediaSubtypesStr[k].c_str());
printf("Subtype=%s\n", buffer);
}
}
DeleteMediaType(pmtConfig);
}
}
printf("\n_______________________________________________________\n\n");
printf("Attention: Not all listed formats are accessable!\nAdvice: Type in the format number.\n\nPlease choose you favourite resolution:\n>>");
/* Choose a listed format for device */
int df = 0;
cin >> df;
VIDEO_STREAM_CONFIG_CAPS scc;
AM_MEDIA_TYPE *pmtConfig;
hr = pConfig->GetStreamCaps(df-1, &pmtConfig, (BYTE*)&scc);
hr = pConfig->SetFormat(pmtConfig);
printf("\n\n");
}
// Query the capture filter for the IAMCameraControl interface.
IAMCameraControl *pCameraControl = 0;
hr = pDeviceFilter->QueryInterface(IID_IAMCameraControl, (void**)&pCameraControl);
if (FAILED(hr)){
printf("\nDevice does not support IAMVideoProcAmp!\n");
// The device does not support IAMCameraControl
}else{
long Min, Max, Step, Default, Flags, Val;
string camPropStr[7] = {"Pan","Tilt","Shutter","Zoom","Exposure","Iris","Focus"};
int camProp[7] = {0,0,0,0,0,0,0};
/*////////////////Read camera properties///////////////*/
printf("\n\nRead camera properties (ranges/defaults/flags)\n");
printf("_______________________________________________________\n\n");
for(int fooInt = CameraControl_Pan; fooInt != CameraControl_Focus+1; fooInt++){
CameraControlProperty foo = static_cast<CameraControlProperty>(fooInt);
hr = pCameraControl->GetRange(foo, &Min, &Max, &Step, &Default, &Flags);
char * buffer = new char[camPropStr[fooInt].length()];
strcpy(buffer,camPropStr[fooInt].c_str());
if (SUCCEEDED(hr))
printf("%s:\n\tMin=%i; Max=%i; Step=%i; Default=%i; Flags=%i\n", buffer, Min, Max, Step, Default, Flags);
else
printf("%s:\n\tCamera has no %s property!\n", buffer, buffer);
}
printf("\n--Camera properties were read successfuly!--\n");
printf("_______________________________________________________\n\n");
////////////////////////////////////////////////////////
/*//////////////Write camera properties//////////////*/
printf("\n\nWrite camera properties (values)\n");
printf("_______________________________________________________\n\n");
for(int fooInt = CameraControl_Pan; fooInt != CameraControl_Focus+1; fooInt++){
CameraControlProperty foo = static_cast<CameraControlProperty>(fooInt);
hr = pCameraControl->Set(foo, camProp[fooInt], CameraControl_Flags_Manual );
char * buffer = new char[camPropStr[fooInt].length()];
strcpy(buffer,camPropStr[fooInt].c_str());
if (SUCCEEDED(hr)){
hr = pCameraControl->Get(foo, &Default, &Flags);
printf("%s (Set):\n\tCurrent=%i; Flags=%i\n", buffer, camProp[fooInt], Flags);
}else
printf("%s (Set):\n\tCamera has no %s property!\n", buffer, buffer);
}
printf("\n--All camera properties got assigned!--\n");
printf("_______________________________________________________\n\n");
////////////////////////////////////////////////////////
}
// Query the capture filter for the IAMVideoProcAmp interface.
IAMVideoProcAmp *pProcAmp = 0;
hr = pDeviceFilter->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);
if (FAILED(hr)){
printf("\nDevice does not support IAMVideoProcAmp!\n");
// The device does not support IAMVideoProcAmp
}else{
long Min, Max, Step, Default, Flags, Val;
string vidPropStr[10] = {"Brightness","Contrast","Hue","Saturation","Sharpness","Gamma","ColorEnable","WhiteBalance","Backlight","Gain"};
int vidProp[10] = {128,32,0,32,24,0,0,0,0,0};
/*////////////////Read video properties///////////////*/
printf("\n\nRead video properties (ranges/defaults/flags)\n");
printf("_______________________________________________________\n\n");
for(int fooInt = VideoProcAmp_Brightness; fooInt != VideoProcAmp_Gain+1; fooInt++){
VideoProcAmpProperty foo = static_cast<VideoProcAmpProperty>(fooInt);
hr = pProcAmp->GetRange(foo, &Min, &Max, &Step, &Default, &Flags);
char * buffer = new char[vidPropStr[fooInt].length()];
strcpy(buffer,vidPropStr[fooInt].c_str());
if (SUCCEEDED(hr))
printf("%s:\n\tMin=%i; Max=%i; Step=%i; Default=%i; Flags=%i\n", buffer, Min, Max, Step, Default, Flags);
else
printf("%s:\n\tThere is no video %s property!\n", buffer, buffer);
}
printf("\n--Video properties were read successfuly!--\n");
printf("_______________________________________________________\n\n");
////////////////////////////////////////////////////////
/*////////////////Write video properties///////////////*/
printf("\n\nWrite video properties (values)\n");
printf("_______________________________________________________\n\n");
for(int fooInt = VideoProcAmp_Brightness; fooInt != VideoProcAmp_Gain+1; fooInt++){
VideoProcAmpProperty foo = static_cast<VideoProcAmpProperty>(fooInt);
hr = pProcAmp->Set(foo, vidProp[fooInt], VideoProcAmp_Flags_Manual );
char * buffer = new char[vidPropStr[fooInt].length()];
strcpy(buffer,vidPropStr[fooInt].c_str());
if (SUCCEEDED(hr)){
hr = pProcAmp->Get(foo, &Default, &Flags);
printf("%s (Set):\n\tCurrent=%i; Flags=%i\n", buffer, vidProp[fooInt], Flags);
}else
printf("%s (Set):\n\tThere is no video %s property!\n", buffer, buffer);
}
printf("\n--All video properties got assigned!--\n");
printf("_______________________________________________________\n\n\n\n");
////////////////////////////////////////////////////////
}
// set FilterGraph
pCaptureGraphBuilder2->SetFiltergraph(pGraphBuilder);
// get MediaControl interface
pGraphBuilder->QueryInterface(IID_IMediaControl, (LPVOID *)&pMediaControl);
// add device filter to FilterGraph
pGraphBuilder->AddFilter(pDeviceFilter, L"Device Filter");
// create Graph
pCaptureGraphBuilder2->RenderStream(&PIN_CATEGORY_PREVIEW, NULL, pDeviceFilter, NULL, NULL);
// start playing
pMediaControl->Run();
// to block execution
// without this messagebox, the graph will be stopped immediately
/*
MessageBox(NULL,
"Block Execution",
"Block",
MB_OK);
*/
system("pause");
// release
pMediaControl->Release();
pCaptureGraphBuilder2->Release();
pGraphBuilder->Release();
}
// release
pEnumMoniker->Release();
pCreateDevEnum->Release();
// finalize COM
CoUninitialize();
return 0;
}