Wie Fotos programmgesteuert mit der Webcam aufnehmen?

Anfängerfragen zum Programmieren mit PureBasic.
Alvos
Beiträge: 3
Registriert: 25.06.2011 13:49

Wie Fotos programmgesteuert mit der Webcam aufnehmen?

Beitrag von Alvos »

Moin,

ich habe seit mehr als 10 Jahren Microcontroller in C programmiert und möchte nun auch endlich Programme für die "großen" Computer schreiben. Die ersten Gehversuche mit Purebasic habe ich unter Windows gemacht. Allerdings finde ich keinen Anfang für das folgende Problem:

Purebasic erhält von einem PC-externen Microcontroller einen Befehl, der eine Variable "Foto" im Purebasic Programm von "0" auf eins "1" ändert. Das funktioniert soweit problemlos. Weiter weiß ich aber nicht: Nun soll in dem Moment, in dem der Wert der Variable wechselt, eine über USB angeschlossene Webcam ein einzelnes Bild hochkant schießen und als jpg oder einem anderen geeigneten Format auf der Festplatte speichern. Dabei soll der Filename das Datum und die Nummer des an dem Tage geschossenen Bildes enthalten. Danach setzt das Programm die Variable "Foto" wieder von "1" auf "0" zurück und der Microcontroller kann das nächste Foto anfordern. Nachdem 50 Fotos geschossen wurden, sollen diese alle gleichzeitig auf dem Bildschirm verteilt in einer Matrix mit 5 Zeilen und 10 Spalten angezeigt werden. Mit den Cursortasten kann man dann zu einem der Bilder navigieren. Durch Betätigen von Enter wird das ausgewählte Bild nun auf Displaygröße vergrößert. Durch nochmaliges Betätigen von Enter wird wieder die Matrix angezeigt.

Da meine Microcontroller nur für Steuerungen eingesetzt wurden, hatte ich nie etwas mit Festplatten, Kameras und Monitoren zu tun. Daher ist das Problem, wie man die Bilder von der Kamera auf die Festplatte und von dort auf den Bildschirm bekommt und wie man den Filenamen in die Bilddatei bastelt. Wie fange ich so etwas an? Gibt es in Purebasic Gadgets, die da hilfreich wären? Die Webcam funktioniert mit Windows Programmen problemlos. Bräuchte man darüber hinaus irgendwelche Treiber oder Sonstiges von Seiten des Webcam Hersteller, um diese unter Purebasic verwenden zu können?

Ich würde mich freuen, wenn man mir ein paar erste Schubser in die richtige Richtung verpassen könnte.

Grüße
Alvos
Benutzeravatar
gnasen
Beiträge: 578
Registriert: 01.08.2007 14:28
Computerausstattung: PB 4.60

Re: Wie Fotos programmgesteuert mit der Webcam aufnehmen?

Beitrag von gnasen »

Zum Thema Webcam könntest du dir folgenden Code mal anschauen, der beinhaltet so einige Dinge bezüglich Webcams und ist von irgendwo aus dem Forum und leicht modifiziert für eine einfachere Anwendung:

Code: Alles auswählen

EnableExplicit

Structure MYCAPDRIVERCAPS 
  wDeviceIndex.l
  fHasOverlay.l
  fHasDlgVideoSource.l
  fHasDlgVideoFormat.l
  fHasDlgVideoDisplay.l
  fCaptureInitialized.l
  fDriverSuppliesPalettes.l
  hVideoIn.l
  hVideoOut.l
  hVideoExtIn.l
  hVideoExtOut.l
EndStructure 
Structure MYCAPTUREPARMS
  dwRequestMicroSecPerFrame.l
  fMakeUserHitOKToCapture.l
  wPercentDropForError.l
  fYield.l
  dwIndexSize.l
  wChunkGranularity.l
  fUsingDOSMemory.l
  wNumVideoRequested.l
  fCaptureAudio.l
  wNumAudioRequested.l
  vKeyAbort.l
  fAbortLeftMouse.l
  fAbortRightMouse.l
  fLimitEnabled.l
  wTimeLimit.l
  fMCIControl.l
  fStepMCIDevice.l
  dwMCIStartTime.l
  dwMCIStopTime.l
  fStepCaptureAt2x.l
  wStepCaptureAverageFrames.l
  dwAudioBufferSize.l
  fDisableWriteCache.l
  AVStreamMaster.l
EndStructure

Structure s_camera
  
  mycapDriver.MYCAPDRIVERCAPS
  mycapSetup.MYCAPTUREPARMS
  hWndC.i
  
EndStructure

Global camera.s_camera

camera\mycapSetup\dwRequestMicroSecPerFrame = 1000000 / 15 ;...I'll capture ~15 frames per sec
camera\mycapSetup\fYield = #True
camera\mycapSetup\dwIndexSize = 1800;...Max frames captured
camera\mycapSetup\fCaptureAudio = #True
camera\mycapSetup\vKeyAbort = #VK_ESCAPE;...Press Esc to stop capture
camera\mycapSetup\fLimitEnabled = #True;...I'll auto end capture after 10 seconds
camera\mycapSetup\wTimeLimit = 10

Procedure CapStatusCallback(hwnd.l, nId.l, lpsz.l)
  ProcedureReturn #True
EndProcedure
Procedure CapYieldCallback(hwnd.l)
  ProcedureReturn #True
EndProcedure

Procedure camera_init(window.i,x.i,y.i,width.i,height.i)
  
  Protected avicap32.i
  Protected *capAddress.i
  
  avicap32 = OpenLibrary(#PB_Any, "avicap32.dll")
  
  If avicap32
    *capAddress = GetFunction(avicap32, "capCreateCaptureWindowA")
    camera\hWndC = CallFunctionFast(*capAddress, 0, #WS_BORDER |#WS_CHILD | #WS_VISIBLE, x, y, width, height, WindowID(window),10)
    CloseLibrary(0)
    SendMessage_(camera\hWndC, #WM_CAP_DRIVER_CONNECT, 0, 0)
    SendMessage_(camera\hWndC, #WM_CAP_SET_PREVIEW, #True, 0)
    SendMessage_(camera\hWndC, #WM_CAP_SET_PREVIEWRATE, 30, 0)
    SendMessage_(camera\hWndC, #WM_CAP_SET_CALLBACK_YIELD, 0, @CapYieldCallback())
    SendMessage_(camera\hWndC, #WM_CAP_SET_CALLBACK_STATUS, 0, @CapStatusCallback())
    UpdateWindow_(camera\hWndC)
  Else
    MessageRequester("Error", "Could not open avicap32.dll", #PB_MessageRequester_Ok | #MB_ICONERROR)
  EndIf
  
EndProcedure
Procedure camera_set_format()
  SendMessage_(camera\hWndC, #WM_CAP_DLG_VIDEOFORMAT, 0, 0)
  UpdateWindow_(camera\hWndC)
EndProcedure
Procedure camera_set_source()
  SendMessage_(camera\hWndC, #WM_CAP_DLG_VIDEOSOURCE, 0, 0)
  UpdateWindow_(camera\hWndC)
EndProcedure
Procedure camera_screenshot(file.s)
  SendMessage_(camera\hWndC, #WM_CAP_FILE_SAVEDIBA, 0, file)
EndProcedure
Procedure camera_end()
  
  SendMessage_(camera\hWndC, #WM_CAP_STOP, 0, 0)
  SendMessage_(camera\hWndC, #WM_CAP_DRIVER_DISCONNECT, 0, 0)
  DestroyWindow_(camera\hWndC)
  
EndProcedure

Define event.i

If OpenWindow(0, 0, 0, 900, 600, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  ButtonGadget(0,800,0,100,20,"screenshot")
  
  camera_init(0,0,0,800,600)
  camera_set_format()
  camera_set_source()
  
  Repeat
    event = WaitWindowEvent()
    
    Select event
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 0 
            Select EventType()
              Case #PB_EventType_LeftClick 
                camera_screenshot(SaveFileRequester("save","screenshot.png","",-1))
            EndSelect
        EndSelect
    EndSelect
    
    If event = #PB_Event_CloseWindow
      camera_end()
      End
    EndIf
    
  ForEver
  
EndIf
pb 4.51
Alvos
Beiträge: 3
Registriert: 25.06.2011 13:49

Re: Wie Fotos programmgesteuert mit der Webcam aufnehmen?

Beitrag von Alvos »

Vielen Dank erstmal für Deine Hilfe :-)

Viele Namen aus Deinem Programm finden sich auch in einem englischen Purebasic Forum und auch in einer Visual Basic
Version wieder, die sich ebenfalls damit beschäftigt, mit Hilfe einer Webcam Fotos zu machen:
http://www.vbarchiv.net/forum/id2_i1229 ... chern.html

Aber als Anfänger habe ich mit einigen Dingen Probleme in Deinem Programm:
Zunächst meckert der Compiler darüber, dass er einige Konstanten nicht kennt: #VK_Escape, #WS_BORDER, #WS_CHILD, #WS_VISIBLE. Wo sollen die Werte also herkommen?
Weiter meint er, SendMessage() sei keine Funktion. Wie soll ich das intepretieren?

Im Programm finden sich zwei Prozeduren, die unabhängig von den Eingangsparametern nicht weiter tun, als ein "True" auszugeben. Wo liegt da der Sinn?:

Code: Alles auswählen

Procedure CapStatusCallback(hwnd.l, nId.l, lpsz.l)
  ProcedureReturn #True
EndProcedure
Procedure CapYieldCallback(hwnd.l)
  ProcedureReturn #True
EndProcedure
Schließlich ist im Programm von einer "avicap32.dll" die Rede. Über *.dll habe ich bisher soviel verstanden, dass es davon eine Menge auf meinem PC gibt, und dass Purebasic sich dafür rühmt, so etwas nicht zu brauchen, weil es nur eine *exe erzeugt. Wieso taucht dann dennoch hier eine solche auf? Mehr weiß ich zum Thema *.dll nicht.

Die Bemerkung, dass Purebasic nur eine Datei (exe) erzeugt, ist für mich als Microcontrollerprogrammierer nichts besonderes, weil auch diese nur eine Datei (hex) vom Compiler geliefert bekommen. Warum ist das denn bei anderen Programmiersprachen anders und welchen Sinn hat das Ganze? Ich wundere mich schon immer darüber, warum manche Programme einen Riesenwust an Verzeichnissen und Dateien im Explorer erzeugen. Warum bestehen andere Programme nicht auch nur eine exe?

Die PureBasic Hilfe hat für keine dieser Bezeichnungen einen Hinweis bereit. Wie komme ich da auf die Sprünge?

Irgendwie bekomme ich das Gefühl nicht los, als wenn zwischen dem Programmieren für den PC und dem für einen Microcontroller Welten liegen. Es ist nämlich so vieles, mit dem man nichts anzufangen weiß, obwohl ich schon über 1000 Seiten gecoded habe.

Was sind Codetags? Wenn ich oben auf "Code" klicke, bekomme ich das hier: Der folgende Abschnitt wird aber nicht in den Kasten übernommen.

Gruß
Alvos

__________________________________________________
Code-Tags angepasst
28.06.2011
RSBasic
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Wie Fotos programmgesteuert mit der Webcam aufnehmen?

Beitrag von RSBasic »

Hallo Alvos,


wenn du Code-Tags verwenden möchtest, musst du vorher deinen Code markieren. Falls dein Browser trotz deiner Markierung das nicht richtig gemacht hat, musst du dafür sorgen, dass vor Beginn deines Codes [code.] (ohne Punkt) steht und am Ende [/code.] (ohne Punkt), dann funktioniert es auch mit dem Anzeigen mit Code-Tags.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Wie Fotos programmgesteuert mit der Webcam aufnehmen?

Beitrag von ts-soft »

Alvos hat geschrieben: Zunächst meckert der Compiler darüber, dass er einige Konstanten nicht kennt: #VK_Escape, #WS_BORDER, #WS_CHILD, #WS_VISIBLE. Wo sollen die Werte also herkommen?
Weiter meint er, SendMessage() sei keine Funktion. Wie soll ich das intepretieren?
Entweder Du nutzt kein Windows oder Du nutzt die Demoversion, in beiden Fällen kann der Code nicht funktionieren!
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Alvos
Beiträge: 3
Registriert: 25.06.2011 13:49

Re: Wie Fotos programmgesteuert mit der Webcam aufnehmen?

Beitrag von Alvos »

ts-soft hat geschrieben:
Alvos hat geschrieben: Zunächst meckert der Compiler darüber, dass er einige Konstanten nicht kennt: #VK_Escape, #WS_BORDER, #WS_CHILD, #WS_VISIBLE. Wo sollen die Werte also herkommen?
Weiter meint er, SendMessage() sei keine Funktion. Wie soll ich das intepretieren?
Entweder Du nutzt kein Windows oder Du nutzt die Demoversion, in beiden Fällen kann der Code nicht funktionieren!
Danke für die Eure Hinweise :-) Und ja, ich benutze die Demo unter Windows Vista. Heißt das. dass ich mit der Demo nicht die Frage nicht klären kann, ob ich meine Problemstellung mit Purebasic erschlagen kann?

Gruß
Alvos
Antworten