Webcam Qualitätsproblem

SCIPIO-AEMILIANUS

aka Dubdidadu
Ich arbeite grad daran einen Motiontracker mithilfe der MFC in C++ anzufertigen.
Gleich am Anfang traf ich auf das Problem, dass ich es nicht schaffe eine ordentliche Qualität aus der Webcam zulocken, die sie eigentlich leisten kann.
Die Farbtiefe/Farbzahl ist nicht sehr groß und auch die Auflösung kommt nur auf 320*240 selbst wenn ich eine Größere einstelle.
Mein Code bisher:
C++:
CAPTUREPARMS Cap;
    hWnd_DLG = capCreateCaptureWindow(L"CameraWindow", WS_CHILD | WS_VISIBLE, 0, 0, 640, 480, GetSafeHwnd(), 1) ;
    capDriverConnect(hWnd_DLG,0);
    capCaptureGetSetup(hWnd_DLG, &Cap, sizeof(CAPTUREPARMS)); 
    Cap.fYield            = false;
    Cap.fCaptureAudio    = false;
    Cap.fLimitEnabled    = false;
    Cap.wTimeLimit        = 0;    
    Cap.dwIndexSize=0;
    capCaptureSetSetup(hWnd_DLG, &Cap, sizeof(CAPTUREPARMS)); 
    capPreviewScale(hWnd_DLG,false) ;
    capPreviewRate(hWnd_DLG,25);
    capPreview(hWnd_DLG,true);
Die Webcam hat 1,3 MP ergo sollte der Code ja zumindest die 640*480 Pixel schaffen. Mir ist bewusst das capPreviewScale und capPreview die beiden bool Parameter die Ausgabegröße beeinflussen jedoch in diesem Fall sollte es auf die maximale Input Maße zurechtschneidern.

Ich hab selbiges mal in Flash realisiert und dort hab ich die 1,3 MP voll ausnutzen können, jedoch halt nicht in C++. Was muss ich tun um dieses zu erreichen?

EDIT: So, ich hab mich noch ein wenig durch Google durchgegraben und herausgefunden das der Treiber standartmäßig von 320*240Pixel bei 16bit farbtiefe ausgeht. Aber wie man es hochsetzt hab ich noch nicht herausfinden können.
 
Zuletzt bearbeitet von einem Moderator:
So, MSDN hat mich nach unzähligen Querverweisen doch noch auf die richtige Spur gelenkt und nachdem ich den BITMAPINFOHEADER auch endlich unter Kontrolle hatte hat das auch geklappt. Mein Ergebnis:
C++:
    CAPTUREPARMS Cap;
    hWnd_DLG = capCreateCaptureWindow(L"CameraWindow", WS_CHILD | WS_VISIBLE, 0, 0, 640, 480, GetSafeHwnd(), 1) ;
    capDriverConnect(hWnd_DLG,0);
    capCaptureGetSetup(hWnd_DLG, &Cap, sizeof(CAPTUREPARMS)); 
    Cap.fYield            = false;
    Cap.fCaptureAudio    = false;
    Cap.fLimitEnabled    = false;
    Cap.wTimeLimit        = 0;    
    Cap.dwIndexSize=0;
    capCaptureSetSetup(hWnd_DLG, &Cap, sizeof(CAPTUREPARMS)); 
    BITMAPINFO bmVidFormat =
    {
        {    sizeof(BITMAPINFOHEADER),
            640,
            480,
            1,
            24,
            BI_RGB,
           640*480*3,
            0,
            0,
            0,
            0,
        },
        {255, 255, 255, 0}
    };
    capSetVideoFormat(hWnd_DLG,&bmVidFormat,sizeof(BITMAPINFO));
    capPreviewScale(hWnd_DLG,false) ;
    capPreviewRate(hWnd_DLG,25);
    capPreview(hWnd_DLG,true);

Bei der Variante sollte man aber, um sicherzugehen, dass man auch nur das von der Kamera abverlangt, was sie wirklich nur leisten kann folgendes am besten benutzen:
C++:
CAPDRIVERCAPS CapDrvCaps; 
capDriverGetCaps(hWnd_DLG, &CapDrvCaps, sizeof (CAPDRIVERCAPS)); 
if (CapDrvCaps.fHasDlgVideoSource)
    capDlgVideoSource(hWnd_DLG); 
CAPSTATUS CapStatus;
if (CapDrvCaps.fHasDlgVideoFormat) 
{
    capDlgVideoFormat(hWnd_DLG); //Öffnet Einstellungs Dialog
    capGetStatus(hWnd_DLG, &CapStatus, sizeof (CAPSTATUS)); //Fragt die Einstellungen ab
}
Aus CapStatus kann man dann die Ausmaße und alles andere dann auslesen.
 
Zuletzt bearbeitet von einem Moderator:
Die uralte VFW-Schnittstelle ist keine so tolle Idee mehr, da man moderne
Webcams damit nur noch im Kompatibilitätsmodus ansprechen kann.
Ausserdem benötigt man Admin-Rechte ...

Viel besser geeignet wäre DirectShow

Ist allerdings auch "etwas" komplizierter :)

Hier ein Anfang:

Code:
 hr = CoInitialize(NULL);

ICaptureGraphBuilder2* pBuilder;

CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC_SERVER,IID_ICaptureGraphBuilder2,(void **)&pBuilder);

Danach Kamera raussuchen, Auflösung einstellen und Filtergraph aufbauen und starten ...

VG
merano
 

Neue Beiträge

Zurück