views:

8517

answers:

4
+13  Q: 

Webcam usage in C#

Hello, I am making a program in C# to connect to a webcam and do some image manipulation with it. I have a working application that uses win32 api (avicap32.dll) to connect to the webcam and send messages to it that sends it to the clipboard. The problem is that, while accesible from paint, reading it from the program results in null pointers.

This is the code I use to connect the webcam:

mCapHwnd = capCreateCaptureWindowA("WebCap", 0, 0, 0, 320, 240, 1024, 0);

SendMessage(mCapHwnd, WM_CAP_CONNECT, 0, 0);
SendMessage(mCapHwnd, WM_CAP_SET_PREVIEW, 0, 0);

And this is what I use to copy the image to the clipboard:

SendMessage(mCapHwnd, WM_CAP_GET_FRAME, 0, 0);

SendMessage(mCapHwnd, WM_CAP_COPY, 0, 0);
tempObj = Clipboard.GetDataObject();
tempImg = (System.Drawing.Bitmap)tempObj.GetData(System.Windows.Forms.DataFormats.Bitmap);

Theres some error checking which I have removed from the code to make it shorter.

Thanks in advance :)

A: 

Have you tried Clipboard.GetImage()? You could also try the various Clipboard.Contains*() methods to see what format the data is stored in the clipboard.

Rob Prouse
I've tryed that. It also returns null
Yourdoom
A: 

My last answer was a load of rubbish...here's something I stole from the web, it's in VB.NET and I lost the C# conversion I did after my portable disk crapped out (serves me right for not using source control).

This may help you sanity check:

http://pastebin.com/f16fe377d

HTH
Kev

Kev
+9  A: 

I've recently started doing some hobby work in this area.

We settled on using the OpenCV library with the opencvdotnet wrapper. It supports capturing frames from a webcam:

using (var cv = new OpenCVDotNet.CVCapture(0))
{
    var image = cv.CreateCompatibleImage();
    // ...
    cv.Release();
}

And if you're doing image manipulation, OpenCV's image processing algorithms have been wrapped within the OpenCVDotNet.Algs assembly.

If you decide to go this route be sure to install OpenCV version 1.0 (and install it to "c:\program files\opencv" if you are on Vista 64-bit, or "mklink OpenCV 'c:\program files (x86)\OpenCV`" from the correct directory or else opencvdotnet will not install).

cfeduke
Thanks! I went this route, after cursing microsoft a bit about mysterious errors I installed Visual C++ 2005 Express and it works great now :)Why the redistributable package didnt work is anyones guess...
Yourdoom
OpenCV.NET is no longer maintained very actively, try Emgu CV if you have no luck with OpenCV.NET
romkyns
+1  A: 

There are really two ways to get camera data into your application, DirectShow and WIA. Microsoft recommends that you use WIA, and the interface for WIA is fairly simple to wrap your brain around. I created and published an open source WIA desktop library based on work I did a while ago.

Now the problem with WIA in some cases is that it's too simple. For example, if you want to adjust camera properties (like frame rate, resolution, etc) then WIA falls down. Microsoft deprecated DirectShow, but they really didn't give us any replacement that has all of its capabilities, and I've found that it continues to work fine on all existing platforms (it's very entrenched, so I can't imagine support going away any time soon).

There is a very good DirectShow library over at SourceForge. The only "problem" with it is it's really complex and that stems from the fact that DShow is just so damned complex and confusing in the first place. There are lots of things that the wrapper can do that just aren't easy to work out, but they do provide samples for a lot of common use cases like showing video or capturing a frame. If you want to add overlays, or insert other filters, it can do it, but be forewarned that it's not at all straightforward.

ctacke
Actually, DirectShow is nowadays the way to go with Windows Vista and 7, and it's far from deprecated with new features still being added in the most recent Windows versions.
Jonas