5

We have a c# application that performs processing on video streams. This is a low-level application that receives each frame in Bitmap format, so basically we need 25 images each second. This application is already working for some of our media sources, but we now need to add a webcam as an input device.

So we basically need to capture bitmap images from a webcam continuously so that we can pass all these frames as a "stream" to our application.

What is the best and simplest way to access the webcam and read the actual frames directly from the webcam as individual images? I am still in the starting blocks.

There are a multitude of libraries out there that allows one to access the webcam, preview the content of the webcam on a windows panel and then use screen capturing to capture this image again. This, unfortunately, will not give us the necessary performance when capturing 25 frames per second. IVMRWindowlessControl9::GetCurrentImage has been mentioned as another alternative, but this again seems to be aimed at an infrequent snapshot rather than a constant stream of images. Directshow.Net is mentioned by many as a good candidate, but it is unclear how to simply grab the images from the webcam. Also, many sources state a concern about Microsoft no longer supporting Directshow. Also, implementations I've seen of this requires ImageGrabber which is apparently also no longer supported. The newer alternative from MS seems to be Media Foundation, but my research hasn't turned up any working examples of how this can be implemented (and I'm not sure if this will run on older versions of windows such as XP). DirectX.Capture is an awesome library (see a nice implementation) but seems to lack the filters and methods to get the video images directly. I have also started looking at Filters and Filter Graphs but this seems awfully complex and does feel a bit like "reinventing the wheel".

Overall, all the solutions briefly mentioned above seem to rather old. Can someone please point me in the direction of a step-by-step guide for getting a webcam working in C# and grabbing several images per second from it? (We will also have to do audio at some point, so a solution that does not exclude video would be most helpful).

Community
  • 1
  • 1
Stanley
  • 5,261
  • 9
  • 38
  • 55

2 Answers2

5

I use AForge.Video (find it here: code.google.com/p/aforge/) because it's a very fast c# implementation. i am very pleased with the performance and it effortlessly captures from two HD webcams at 30fps on an 8 year old PC. the data is supplied as a native IntPtr so it's ideal for further processing using native code or opencv.

opencv wrappers emgu and opencvsharp both implement a rudimentary video capture functionality which might be sufficient for your purposes. clearly if you are going perform image processing / computer vision you might want to use those anyway.

morishuz
  • 2,302
  • 4
  • 21
  • 21
  • Thank you for the suggestion of using AForge, but can you perhaps give some more details about your suggested solution? It is very high level and doesn't bring me much closer to implementing a solution. I am a bit of a beginner in all this and your answer seems to assume quite a bit of background knowledge on my part. – Stanley May 03 '13 at 11:32
  • ok so i am assuming you have base level knowledge of c# at least? if you download AForge, run the examples and have a look at how it works you should be able to figure out how the video grabber works - or at least how to interface with it. if you then have questions you can post them here, but right now i am not sure how to help you. what specifically are you struggling with? what have you tried? – morishuz May 03 '13 at 11:53
  • 1
    Have a look at the MotionDetector sample in `Aforge\Samples\Vision`. The method `openJPEGURLToolStripMenuItem_Click` in `MainForm.cs` will get you started. – JeffRSon May 03 '13 at 11:56
  • 1
    Thank you so very much! I did some googling on my own and checked out some of the resources on Aforge. I was able to get it working using a modified version of the code from http://en.code-bude.net/2013/01/02/how-to-easily-record-from-a-webcam-in-c/ I'll add the details in a separate answer to help someone else too, but I'll accept your answer since it pointed me to Aforge. – Stanley May 03 '13 at 12:16
4

As dr.mo suggests, Aforge was the answer.

I used the tutorial from here: http://en.code-bude.net/2013/01/02/how-to-easily-record-from-a-webcam-in-c/

In the tutorial, they have an event handler fire each time a frame is received from the webcam. In the original tutorial, this bitmap is used to write the image to a PictureBox. I have simply modified it to save the bitmap image to a file rather than to a picturebox. So I have replaced the following code:

pictureBoxVideo.BackgroundImage = (Bitmap)eventArgs.Frame.Clone();

with the following code:

Bitmap myImage = (Bitmap)eventArgs.Frame.Clone();
string strGrabFileName = String.Format("C:\\My_folder\\Snapshot_{0:yyyyMMdd_hhmmss.fff}.bmp", DateTime.Now);            
myImage.Save(strGrabFileName, System.Drawing.Imaging.ImageFormat.Bmp);

and it works like a charm!

Stanley
  • 5,261
  • 9
  • 38
  • 55