Webcam Bild erzeugen/Lösungsansätze



  • Hey Leute,

    wir müssen im Laufe unsere Projektwoche eine Dokumentenkamera erstellen. Dazu müssen wir über den Borland-Builder 2010 eine Webcam ansteuern. Das Problem dabei ist, dass unser Lehrer nicht gerade hilfreich ist. Wir haben bereits einen Blick auf das AllanPetersen WebCam Programm geworfen, jedoch konnten wir uns damit auch nicht helfen, da die Struckturanfänge für uns nicht ersichtlich sind.
    Nun zu meiner Frage:
    Wie steuert man die Webcam an, bzw. wie fängt man an ein Bild im Builder zu erzeugen? Eine Videoobjekt gibt es ja leider nicht.

    Ich hoffe ihr könnt uns helfen( JA, SuFu wurde benutzt!)

    LG



  • Eine Minute Google-Suche brachte mich zu ESCAPI - Extremely Simple Capture API:

    Jari Komppa schrieb:

    Simple DLL interface to use video capture devices (i.e. webcams), along with a simple example that uses SDL, as well as a couple even simpler examples that don't require SDL. 2.1 adds examples for BlitzMax, PureBasic, as well as a OpenGL-based "funny mirrors"-example. The only DLL change is that the 'alpha' bits now have value 0xff.
    The DLL is free for anyone to use as long as I'm not held responsible for anything.

    Das sollte helfen. Ansonsten: DirectShow direkt ansteuern.



  • Hallo,

    Allan Petersen hat mit der Version WebCam 2.1 ein sofort lauffähiges (zumindest BCB2009) Projekt ins Netz gestellt.
    Solltet ihr diesen Link meinen :
    http://allanpetersen.com/wp-content/plugins/download-monitor/download.php?id=10

    dann habt ihr die beste Grundlage. Ansonsten Verständnisprobleme beheben 😉

    mfg
    kpeter



  • Hallo,
    ich hänge mich einfach mal an das Thema ran, und zwar möchte ich "einfach" in das Webcam Bild bei der Software von Allan Petersen, WebCam 2.1, ein Fadenkreuz einblenden. Wenn möglich sollte dieses auch in X und Y Position verschiebbar sein und gegeben falls auch vergrößert und verkleinert werden...
    Soweit habe ich C++ Builder und das Projekt am laufen, ich komme leider aus der Mikrocontroller Ecke und habe mit C++ und Konsorten noch nicht viel am Hut gehabt etwas Java das war es dann aber schon. Es gibt also noch reichlich Verständnis Probleme, ich werde mal schauen was es bei uns an der FH Literatur zum Thema gibt, aber die erste Frage wäre an diese Stelle ob es überhaupt Sinn macht die Software von Petersen an zu passen oder ob es der Flasche weg ist?!

    Lg der Muck



  • the_muck schrieb:

    Hallo,
    ...in das Webcam Bild bei der Software von Allan Petersen, WebCam 2.1, ein Fadenkreuz einblenden.

    Ist möglich, indem du auf den Device Context des CaptureWindow innerhalb der WM_TIMER Botschaft zeichnest.
    An diese WM_TIMER kommst du über Application->OnMessage heran.

    Dazu wird immer die aktuelle Cursorposition abgefragt.

    mfg
    kpeter



  • Vielen Dank für die Hilfe soweit!

    Haben inzwischen ein Bild bekommen! Und zwar:

    void __fastcall TDokuCam::FormCreate(TObject *Sender)
    {
      HWND hWebcam;
      HWND hwnd = web_bild->Handle;    //Handel vom Panel -> darauf wird der Webcam Stream gelegt
    
      hWebcam = capCreateCaptureWindow("Capture Window", WS_CHILD | WS_VISIBLE,0, 0, web_bild->Width, web_bild->Height,hwnd, 0);
    
      SendMessage(hWebcam, WM_CAP_DRIVER_CONNECT,0, 0);
      SendMessage(hWebcam, WM_CAP_SET_SCALE,1, 0);
      SendMessage(hWebcam, WM_CAP_SET_PREVIEWRATE,10,0);
      SendMessage(hWebcam, WM_CAP_SET_PREVIEW,1,0);
    

    Jedoch zum nächsten Problem 😞
    Sobald wir die Größe von dem Fenster ändern, bleibt das Video so bestehen wie es ist. Das Panel lässt sich bereits in der Größe verändern, jedoch nicht das Videobild. Wie kann ich nachträglich auf die Größe von dem Videohandle zugreifen? Mit hWebcam->Height geht das ja nicht.
    Nochmal der Code zum Panel:

    void __fastcall TDokuCam::FormResize(TObject *Sender)
    {
    web_bild->Height=DokuCam->ClientHeight-40;
    web_bild->Width=DokuCam->ClientWidth-160;
    }
    


  • SetWindowPos und SetWindowPosition aus der Win32 API sollten gehen.



  • Haben es mit der SetWindowPos() probiert, jedoch passiert dabei nichts, machen wir was falsch?
    Steht ebenfalls in der FormRezise drinne

    SetWindowPos(      
        hwnd,
        hWebcam,
        0,
        0,
        50,       //Test
        50,       //Test
        0);
    


  • Hallo,

    mit folgendem Code wird die DialogBox Videoformat geöffnet.

    void __fastcall TForm1::sbVideoFormatClick(TObject *Sender)
    {
        capDlgVideoFormat(hCap);
        CAPSTATUS CapStatus;
        capGetStatus(hCap, &CapStatus, sizeof(CAPSTATUS));
        int wi = CapStatus.uiImageWidth;
        int hi = CapStatus.uiImageHeight;
    
        Panel1->SetBounds( 8, 72, wi, hi);
        SetWindowPos(hCap, NULL, 0, 0, wi, hi, SWP_NOZORDER | SWP_NOMOVE);                   
    }
    

    Beachtet die Reihenfolge der Fensteranpassungen. Panel1 ist das Parent-Fenster.

    mfg
    kpeter

    edit: natürlich gehts auch ohne Dialogbox, entscheidend ist, dass der Status abgefragt wird (ab Zeile 4).
    Der Dialog ist interessant wegen der bevorzugten Formate Breite/Höhe.



  • //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #include <vfw.h>  			//Video For Windows
    #include <windows.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TDokuCam *DokuCam;
    	HWND hWebcam;
    	HWND hwnd;
    //---------------------------------------------------------------------------
    __fastcall TDokuCam::TDokuCam(TComponent* Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TDokuCam::Beenden1Click(TObject *Sender)
    {
    Application->Terminate();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TDokuCam::FormCreate(TObject *Sender)
    {
      HWND hWebcam;
      HWND hwnd = Panel1->Handle;    //Handel vom Panel -> darauf wird der Webcam Stream gelegt
    
      hWebcam = capCreateCaptureWindow("Capture Window", WS_CHILD | WS_VISIBLE,0, 0, Panel1->Width, Panel1->Height,hwnd, 0);
    
      SendMessage(hWebcam, WM_CAP_DRIVER_CONNECT,0, 0);
      SendMessage(hWebcam, WM_CAP_SET_SCALE,1, 0);
      SendMessage(hWebcam, WM_CAP_SET_PREVIEWRATE,10,0);
      SendMessage(hWebcam, WM_CAP_SET_PREVIEW,1,0);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TDokuCam::FormResize(TObject *Sender)
    {
    	capDlgVideoFormat(hWebcam);
    	CAPSTATUS CapStatus;
    	capGetStatus(hWebcam, &CapStatus, sizeof(CAPSTATUS));
    	int wi = CapStatus.uiImageWidth;
    	int hi = CapStatus.uiImageHeight;
    
    	Panel1->SetBounds( 5, 5, DokuCam->Width-160, DokuCam->Height-40);
    	SetWindowPos(hWebcam, NULL, 0, 0, wi, hi, SWP_NOZORDER | SWP_NOMOVE);
    }
    //---------------------------------------------------------------------------
    

    Einmal der komplette Code soweit. Selbe Problem wie zuvor, es ändert sich NUR das Panel, das Videobild bleibt unberührt, egal welche Werte ich in die SetWindowsPos() schreibe. Was machen wir falsch?
    Habe als Test mal die Werte für wi und hi abgefragt, wobei wi=0 und hi=-1 war, muss das so sein?

    MFG



  • Hallo,

    sehr kompakter und minimalistischer Code 😉 .

    Die Fenster Handle sind nicht korrekt platziert.

    Header-Dekl. in Zeile 13, 14 und 29 löschen und in private setzen:

    // *.h-Datei:
    
    private:
       HWND hWebcam;
       HWND hwnd;
    

    Zeile 30 in der *.cpp heisst dann nur

    hwnd = Panel1->Handle;
    

    Beim Beenden des Programmes muss noch disconnected werden (spätestens im Destruktor).
    Das Erstellen des Video-Fensters würde ich komplett in den Konstruktor verlagern; OnFormCreate sollte nicht (mehr) verwendet werden.
    Dazu gibts auch im Forum Beiträge.

    mfg
    kpeter

    edit1: Die SendMessages geben jeweils einen Boolscher Wert, je nach Erfolg, zurück.
    Dieser sollte vor Ausführen der folgenden SendMessage ausgewertet werden. Also in der Art

    if (!SendMessage(hWebcam, WM_CAP_DRIVER_CONNECT,0, 0))
          return;
    

    edit2:

    Das hier

    Panel1->SetBounds( 5, 5, DokuCam->Width-160, DokuCam->Height-40); 
       SetWindowPos(hWebcam, NULL, 0, 0, wi, hi, SWP_NOZORDER | SWP_NOMOVE);
    

    erzeugt mit Sicherheit einen Ausschnitt des Videofensters, wenn das Panel kleiner als wi, hi ist;
    Breite und Höhe sind verschieden.
    Gibts dafür einen Grund?



  • Vielen Dank!

    if (!SendMessage(hWebcam, WM_CAP_DRIVER_CONNECT,0, 0))
          return;
    

    Das wars gewesen! Brauch dabei auch den CAPSTATUS etc nichtmehr sondern nurnoch die SetWindowsPos().

    Jetzt wird sich an die Schwarz/weiß Funktion, Kontrast-, Farbe-, Helligeit- Balken gesetzt!, wenn wir (malwieder) nicht weiterkommen, meld ich mich 😉

    Nochmal ne Frage:
    Wieso sollte man die Videostellung im Konstruktor machen und nicht (mehr) in der FormCreate? Gibt es dafür einen Grund?



  • hat-schii schrieb:

    Wieso sollte man die Videostellung im Konstruktor machen und nicht (mehr) in der FormCreate?

    Hier der weiterführende Link , ab ca. Mitte des Threads.



  • Moin, moin,
    ich habe ein ähnliches Projekt am Laufen und ich versuche grad eine zoomfunktion einzubauen, hab bisher aber keinen Zoom für Videostreams (vfw) gefunden.

    Danke für eure Hilfe



  • Hallo,

    in MCI-Devices ist Zooming möglich. Mit dem Makro capSetMCIDeviceName leitet man den Videostream weiter.
    Hier der Link dazu.
    Probiert hab ichs selbst noch nicht...
    mfg
    kpeter

    edit: Möglicherweise gehts nur in Richtung MCIDevice->CaptureWindow.
    Eine andere Möglichkeit ist die Frames auszulesen und zu stretchen.



  • Gibt es eine Möglichkeit das Hauptformular durch einen Befehl zu maximieren?

    Zoom und die Einstellungen der Farbe etc machen auchnoch Probleme, aber da sind wir grad eifrig dabei 😉 Die MCI Devices haben uns soweit nicht geholfem wahrscheinlich haben wir sie falsch verwendet

    MFG



  • Bei der Zoomfunktion hab ich jetzt einen Button erstellt, der folgendes machen soll:

    void __fastcall TDokuCam::Zoom_BClick(TObject *Sender)
    {
     capSetMCIDeviceName(hWebcam, web_bild);
     MCIWndSetZoom(hWebcam,200);
    }
    

    ich hab kA warum nichts passiert, weil ich irgentwie die MCI-Funktionen nicht versteh.



  • hat-schii schrieb:

    Gibt es eine Möglichkeit das Hauptformular durch einen Befehl zu maximieren?

    WindowState = wsMaximized;
    

Log in to reply