3.2k Aufrufe
Gefragt in Anwendungen(Java,C++...) von computerschrat Profi (32.2k Punkte)
Hallo zusammen,

ich möchte in einem VB Programm zwei identische USB Webcams in je einer eigenen PictureBox anzeigen und dann deren Bilder weiterverarbeiten.


Mein Problem ist, dass die Initialisierung der Kameras nicht immer funktioniert. Ich habe die (hoffentlich) relevanten Codeabschnitte unten angehängt. Er besteht aus zwei Teilen.

Deklaration einer Klasse iCam
(quelle: http://www.vbforums.com/showthread.php?344471-Vb.Net-WebCam-Class-%28ICam%29)

Dann das VB-Form, in dem die Anwendung steht. Hier wird zunächst jede Kamera deklariert. Dann wird im Form_Load für beide eine eigene Instanz initialisiert. Später wird dann mit StartCam1 und StartCam2 jede der beiden Kameras gestartet. Hierzu wird der Verweis auf die jeweils der Kamera zugeordneten PictureBox übergeben. Da die beiden PB's auf einem anderen Form namens Kameras stehen, erfolgt die Übergabe mit Kameras.pbCAM1.

Die Funktion initCam stellt zunächst die Verbindung mit dem Vorschaufenster her, das funktioniert immer. Dann kommt der Aufruf von setCam. Bei der ersten Kamera (egal ob Cam1 oder Cam2) funktioniert es immer. Es öffnet sich der Dialog zur Auswahl der Kamera, und nach Auswahl einer der beiden vorhandenen Kameras kommt auf die Nachricht WM_CAP_DRIVER_CONNECT immer ein true zurück. Anschließend erscheint das Kamerabild in der PictureBox.
Bei der zweiten Kamera kommt leider meistens kein Auswahldialog und dann ein false zurück.

Wenn die Initialisierung funktioniert hat, geht der Rest immer einwandfrei und stabil. Wenn die Initialisierung der zweiten Kamera nicht funktioniert hat, dann hilt gelegentlich ein einfacher Neustart des Debuggers ohne irgendeine Veränderung in er Quelle! Oft muss ich es fünf, sechsmal hintereinander probieren, bis es dann geht. Allerdings geht es nur, wenn ich in der Entwicklungsumgebung (Visual Basic Express 2010 bzw 2012) im Debug Mode arbeite. In der erzeugten Exe geht die zweite Kamera nie.

Was mache ich bei der Nutzung der beiden Kameras falsch?

Bei Bedarf lade ich auch gerne mehr vom Code hoch, zunächst wollte ich die Codemenge möglichst klein halten.

Gruß und Danke für Eure Unterstützung

computerschrat


Hier nun der Auszug aus dem Code:
#########################################################
Public Class iCam
...
...

Private iDevice As String
Private hHwnd As Integer
Private lwndC As Integer

Public iRunning As Boolean

Private CamFrameRate As Integer = 10
Private OutputHeight As Integer = 480
Private OutputWidth As Integer = 640
...
...

Public Sub initCam(ByVal parentH As Integer)
'Gets the handle and initiates camera setup
If Me.iRunning = True Then
MessageBox.Show("Camera Is Already Running")
Exit Sub
Else

hHwnd = capCreateCaptureWindowA(iDevice, WS_VISIBLE Or WS_CHILD, 0, 0, OutputWidth, CShort(OutputHeight), parentH, 0)

If setCam() = False Then
MessageBox.Show("Error setting Up Camera")
closeCam()
End If
End If
End Sub

Private Function setCam() As Boolean
'Sets all the camera up

If SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, CShort(iDevice), CType(0, String)) = 1 Then
SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, CShort(CamFrameRate), CType(0, String))
SendMessage(hHwnd, WM_CAP_SET_PREVIEW, 1, CType(0, String))
Me.iRunning = True
Return True
Else
Me.iRunning = False
Return False
End If
End Function
...
...
Public Function closeCam() As Boolean
'Closes the camera
If Me.iRunning Then
closeCam = CBool(SendMessage(hHwnd, WM_CAP_DRIVER_DISCONNECT, 0, CType(0, String)))
Me.iRunning = False
End If
Return Me.iRunning
End Function
...
...
End Class


Und hier der zweite Teil
#####################################################################

Imports System.IO


Public Class Form1

Inherits System.Windows.Forms.Form
...
...
Private Cam1 As iCam
Private Cam2 As iCam
...
...
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

Cam1 = New iCam
Cam2 = New iCam
...
...
End Sub


Private Sub StartCam1()
Cam1.initCam(Kameras.pbCam1.Handle.ToInt32)
...
...
End Sub

Private Sub StartCam2()
Cam2.initCam(Kameras.pbCam2.Handle.ToInt32)
...
...
End Sub

5 Antworten

0 Punkte
Beantwortet von solo Mitglied (161 Punkte)
ach computerschrat, du und kalle, ihr seit doch die top member des supportnet. klar das da keiner das wasser reichen kann und deshalb gab es keine antwort auf diesen thread. also nicht traurig sein!
0 Punkte
Beantwortet von computerschrat Profi (32.2k Punkte)
Hallo solo,

danke für die Blumen. Eigentlich fühle ich mich gar nicht so :-) Ich bin auf das Suche nach einer Lösung für dieses Problem erstmals auf das Supportnet gestoßen und fand die Idee gut. Mir macht es Spaß an der einen oder anderen Problemlösung mitzuwirken.

Und mein Kameraproblem war in VB selbst durch den Microsoft Developer Support nicht zu lösen. Nur durch Umstieg auf C# läuft es jetzt einwandfrei.

Gruß
computerschrat
0 Punkte
Beantwortet von kjg17 Profi (34.4k Punkte)
Hallo computerschrat,

wir spielen uns bei anderen Usern zwar öfter mal erfolgreich den Ball zu, aber von VB habe ich nun wirklich keine Ahnung.

Aber sei´s drum:
Könnte man 'setCam' nicht direkt mit VB realisieren, z.B. anhand der ja unterschiedlichen Serien-Nummern der Web-Cams, sofern sich diese per VB auch auslesen ließen?
Oder könnte eventuell eine Anweisung fehlen, die Anzeige der Cams in jeweils eigenen Prozessen auszuführen?

Falls das jetzt absoluter Schwachsinn ist, hau´s einfach in die Tonne. ;o)

Gruß
Kalle
0 Punkte
Beantwortet von computerschrat Profi (32.2k Punkte)
Hallo Kalle,

das mit dem Ball zuspielen macht ja auch Vergnügen.

Das Problem mit den beiden Kameras ist nicht so richtig zu verstehen und die Erklärung von Microsoft ist mir auch nicht ganz verständlich. Mein Problem war ja, dass ich zwar jede Kamera einzeln problemlos ansprechen konnte und gelegentlich auch beide. Meistens aber ging die zweite angesprochene Kamera nicht und das im unveränderten Programm, ohne auch nur das Entwicklungssystem überhaupt angeworfen zu haben.
Microsoft meint, das läge am veralteten System Video für Windows, das ich benutzt hätte und am Managed Code. Bei dem wüsste man nie genau, wann irgendwelche Garbage Collections liefen und deshalb könnte es zu solchen Effekten kommen. Na wie auch immer, nach dem Umstieg auf C# und Direct Show läuft es nicht nur stabil, sondern auch wesentlich schneller.

Möglicherweise hätte Dein Vorschlag auch zum Erfolg geführt. Vielleicht teste ich das später auch mal aus reinem Interesse.

Gruß
computerschrat
0 Punkte
Beantwortet von kjg17 Profi (34.4k Punkte)
Hallo computerschrat,

Vielleicht teste ich das später auch mal aus reinem Interesse.

Vermutlich aber nur, wenn es im SN nichts Sinnvolleres für dich zu tun gibt. ;o)

Gruß
Kalle
...