Laden...

WebCam mittels VFW in C#

Erstellt von egrath vor 17 Jahren Letzter Beitrag vor 14 Jahren 39.483 Views
egrath Themenstarter:in
871 Beiträge seit 2005
vor 17 Jahren
WebCam mittels VFW in C#

Hallo,

da schon einige male anfragen waren, wie man WebCams mittels C# ansprechen kann, hab ich mal ein kleines Beispiel zusammengehackt welches über die Video for Windows Schnittstelle einen Videostream von der Webcam in einem Form darstellt. In einem zweiten Teil der Form wird das selbe Video, allerdings geflippt dargestellt. Dies soll demonstrieren wie man mittels Callback Methoden das eingehende Video on the Fly ändern kann.

Bitte nicht über die Qualität des Codes schimpfen, ist relativ Quick-n-Dirty.

Grüsse, Egon

/edit: Neue Version, folgende änderungen:

  • Wesentlich verbesserte Performance (Danke für den Tipp an tom-essen)
  • Ordentliche Kapselung zwischen den Teilen
  • Image wird korrekt in den Buffer geschrieben
  • Einstellbare Frameraten und Videogrössen
egrath Themenstarter:in
871 Beiträge seit 2005
vor 17 Jahren

... und der Source

/edit: Neue Version

1.820 Beiträge seit 2005
vor 17 Jahren

Hallo!

Interessantes Projekt, hab's gleich ausprobiert!
Funktioniert zwar auch, allerdings zeigt er nur ca. alle 5 Sekunden ein Bild an, liegt das vielleicht an den ganzen Marshalling-Funktionen?

Aber insgesamt wirklich überraschend, wie einfach der Zugriff ist.

Nobody is perfect. I'm sad, i'm not nobody 🙁

egrath Themenstarter:in
871 Beiträge seit 2005
vor 17 Jahren

Hallo,

es sollten 5 Frames/sec angezeigt werden (WM_CAP_SET_PREVIEWRATE auf 200) - allerdings aus einem Grund den ich nicht ganz verstehe, hab ich im Debugger das gleiche Phänomen wie du beschreibst (alle 5 sek ein Bild; Der Verursacher der Delays ist die Callback Methode, habs aber nicht genauer getraced). Ohne Debugger läufts in der angegebenen Framerate.

Grüsse, Egon

1.820 Beiträge seit 2005
vor 17 Jahren

Hallo!

Stimmt, im VS nur ca. alle 5sek, egal ob als DEBUG oder RELEASE, und direkt gestartet läuft's richtig gut.

Hab's gerade rausgefunden:


//for( int index = imageData.Length-1; index > 0; index-- )
//{
//    Marshal.WriteByte( bmpData.Scan0, index, imageData[index] );
//}
Marshal.Copy(imageData, 0, bmpData.Scan0, imageData.Length);

Zeile 59 im Hauptprogramm, dann läuft's super

Nobody is perfect. I'm sad, i'm not nobody 🙁

egrath Themenstarter:in
871 Beiträge seit 2005
vor 17 Jahren

Neue Version, siehe oben.

1.820 Beiträge seit 2005
vor 17 Jahren

Hallo!

Genial! Was es mit so einer Anwendung auf einmal Spaß macht, sich selbst zu beobachten 😁

Nobody is perfect. I'm sad, i'm not nobody 🙁

E
34 Beiträge seit 2007
vor 16 Jahren

Das beispiel ist genial, hab da mit nun ein bisschen gespielt und klappte auf Anhieb...

Bin Beuling in C#.

Nun wollt ich in einem eigenen neuen Projekt das versuchen, aber es will einfach nicht klappen. Erstelle eine Windows Anwendung in C# und verweise dann noch auf die AVICapWrapper.dll aber wenn ich dann mit einem panel bzw dem aviCapture1 objekt arbeiten will sol ich immer new benutzen...

ich hoffe, jemand kann mir weiterhelfen,
danke schon mal in voraus!

Edit, hab gerade festgestellt, das beim taskmanager der speicher immer mehr anwächst, kann man das verhindern?

Der größte Fehler ist der menschliche Verstand.
besucht uns auf www.codedragon.de

P
1 Beiträge seit 2007
vor 16 Jahren

hallo.
cooles programm jedoch habe ich 2 probleme

beim wechseln auf 640x480 kommt bei mir folgende fehlermeldung.

"argumentoutofrangeexception wurde nicht behandelt, der angeforderte bereich geht über das arrayende aus"

diese zeile wird dabei gelb markiert.

Marshal.Copy( imageData, ( row * m_VideoFormat.bmiHeader.biWidth * 3 ), new IntPtr( startAddr ), m_VideoFormat.bmiHeader.biWidth * 3 );

noch etwas anderes. beim bild sind da so verzerrungen, also wie horizontale streiffen im bild zu erkennen. wenn ich den stream in windows movie maker ansehe ist das nicht so.

habt ihr irgendwelche vorschläge?

vielen dank im voraus.

mfg pascal

J
49 Beiträge seit 2007
vor 15 Jahren

auch wenn es vll keinen mehr interessiert....

beim wechseln auf 640x480 kommt bei mir folgende fehlermeldung.

"argumentoutofrangeexception wurde nicht behandelt, der angeforderte bereich geht über das arrayende aus"

diese zeile wird dabei gelb markiert.

Marshal.Copy( imageData, ( row * m_VideoFormat.bmiHeader.biWidth * 3 ), new IntPtr( startAddr ), m_VideoFormat.bmiHeader.biWidth * 3 );"

läßt sich mit
imageData = new byte[m_VideoFormat.bmiHeader.biWidthm_VideoFormat.bmiHeader.biHeight3];
vor der gelb markierten schleife umgehen... irgendwie wird ist da die größe in

byte[] imageData = new byte[vhdr.dwBytesUsed];
falsch.

ich hab das prob, dass das frame-von-buffer fenster immer schwarz ist 🙁
kann also nicht direkt bmps vom stream holen - irgendwie... falls
jemand fix ne lösung weiß, melden ^^ ansonsten werd ich schon irgendwie anders drankommen, wenn net durch dieses projekt, dann durch ein anderes 🙂

mfg JL

K
80 Beiträge seit 2006
vor 15 Jahren

Also zu der Exception würde ich mal sagen: Das ist so nicht handlebar wie oben beschrieben, denn die Desktop cams haben eine bestimmte max auflösung, die wird im Puffer durch den Videoheader ja auch richtig geholt. Wenn man den Puffer jetzt künstlich vergrößert, wird das Bild das ihr von der Cam bekommt noch immer nicht größer.
Ich weiß nicht wie man in VfW die Max Auflösung bekommt, die API ist IIRC auch recht alt und man sollte eher DirectShow verwenden ( gibt auf Sourceforge nen guten .net Wrapper ). Wenn man über die Max native Auflösung gehen will, muss man das Bild das man im Puffer bekommt selbst skallieren. Die lösung den Buffer so anzupassen ist auf jedenfall falsch und sollte so nicht angewendet werden.

479 Beiträge seit 2008
vor 14 Jahren

Für mich irgendwie unbrauchbar... X(
Stürzt ständig ab und der Buffer funktioniert überhauptnicht. Außerdem hakt das Fenster bei jedem Frame 🙄

mfg.
markus111

[Follow me on Twitter](http://twitter.com/blendingsky)
49.485 Beiträge seit 2005
vor 14 Jahren

Hallo markus111,

vermutlich bezieht sich deine Aussage auf Windows 7. Bei so hardware-nahen Funktionen, kann es schon mal sein, dass es mit neueren Betriebssystemversionen Probleme gibt. Nach dem, was die anderen schreiben, läuft es - auch wenn dir persönlich das nichts nutzt - aber unter (vermutlich) Windows XP stabil.

Ein weitere Grund könnten bei Treiber-Konflikten liegen. Es bietet sich an, die neueste stabile Treiberversion zu verwenden.

Wenn alles nichts hilft, tja, dann ist dieses Projekt für deinen Einsatzfall bzw. deine Umgebung eben nichts.

herbivore

Y
25 Beiträge seit 2009
vor 14 Jahren

Also ganz ehrlich, auch wenn ein paar kleine Probleme auftreten, von meiner Seite ein super, gelungenes Projekt!

Danke für deine Arbeit!

S
3 Beiträge seit 2010
vor 14 Jahren

Hallo,

Zum ersten: wirklich ein schönes Tool

Aber ich hätte noch eine mehr oder weinger allgemeine Frage.
Wisst ihr eine Möglichkeit wie man die WebCam wechseln kann?
Ich habe bei mir zwei WebCams am PC angeschlossen, ich weis auch schon das man über ein SendMessage einen "Select Source" Dialog öffnen lassen kann wo man die jeweilige WebCam des verwendeten Treibers wählen kann.

Die Eigentliche Frage von mir ist, ob jemand weis wie ich die gewünschte WebCam über das Programm wählen kann "ohne" diesen Dialog öffnen zu lassen (sprich ohne das ich als Bediener das tun muss.

Würde gerne ein Programm machen das mir auf einer Form den Stream von beiden WebCams darstellt.

Gruß Sven

F
4 Beiträge seit 2007
vor 14 Jahren

Hi,

also ich bekomme leider nur diesen Auswahldialog für das Wählen der WebCam, aber leider kein Bild angezogen.

Kann mir da jemand weiterhelfen?

Danke
Florian

S
3 Beiträge seit 2010
vor 14 Jahren

Ja habe zwischenzeitlich mal etwas mehr rein investiert.
Leider scheint es keine andere Möglichkeit zu geben das Gerät zu wechseln auser dem blösen Dialog...
Bin jetzt auf DirectX umgestiegen... genauso langsam beim verbinden zu einer Kamera, aber bedeutend mehr möglichkeiten 😃

@Foggie200
Bekommst du ein schwarzes Bild angezeigt?
Wenn ja prüf mal deinen Kammeratreiber. Hatte auch das Problem das ich nur eine schwarte Fläche angezeigt bekommen habe aber in den Windows Einstellungen hatte man ein Livestream gesehen...
Musste mir dann den Treiber der Kamera (bei mir eine Logitech WebCam) laden und installieren. Dann erst ging es...

F
4 Beiträge seit 2007
vor 14 Jahren

hmm... also eigentlich hab ich den aktuellsten Treiber drauf, allerdings bei Win7.

Wie machst du das mit DirectX? Über das Codeproject - Teil mit DirectX.Capture?

Ich bräuchte eigentlich nur eine einfache Kameraanbindung, bei der ich dann die Bilder einzeln auswerten kann. Vielleicht weist du ja was.

Danke
Flo

S
3 Beiträge seit 2010
vor 14 Jahren

Ja ich habe auf das Beispiel von CodeProject aufgesetzt:
DirectX.Capture Class Library (Refresh) <<< Das hier war es glaub ich.
Ist war etwas triggi um an ein Bild ran zu kommen, aber sonst ein richtig schönes Ding 😃

Aber wenn du nur eine Kamera ansteuern willst sollte die DLL vollkommen ausreichen.
Dort weis ich nun auch nicht weiter... bei mir schien es ein Treiber problem gewesen zu sein.
Hatte aber WinXp als Betriebssystem. Unter Win7 habe ichs noch nicht probiert, auf Win7 hatte ich dann nur DirectX getestet.

2.921 Beiträge seit 2005
vor 14 Jahren
Realtime Videobearbeitung

Ich belebe mal diesen Thread ein wenig wieder. @Egrath:

Hab heute dein Programm hier ausgegraben und mir mal erlaubt das mit der LowLevelGraphicsLibrary zu verbinden.

An der Stelle an der Du mit den Schiebereglern den Wert ausliest der eingestellt wurde, wird jetzt der in der ComboBox ausgewählte Filter benutzt, wenn möglich.

Jetzt kann jeder mal ausprobieren was das für Auswirkungen haben kann.

Hinweis:

Da das momentan die aktuellste Library ist können Abstürze auftreten. Ich bin aber momentan daran alle zu beheben.

Ich hoffe das ist ok für Dich Egrath. 😃

Das veränderte Programm von Dir gibt's hier als Anhang

EDIT: Anhang jetzt online, hat vorher nicht mit hochladen geklappt

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.