22

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 accessible 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);

There's some error checking which I have removed from the code to make it shorter.

cottontail
  • 10,268
  • 18
  • 50
  • 51
Elva
  • 1,003
  • 2
  • 9
  • 20

5 Answers5

17

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
  • 23,100
  • 10
  • 61
  • 65
  • 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... – Elva Oct 28 '08 at 13:43
  • 4
    OpenCV.NET is no longer maintained very actively, try Emgu CV if you have no luck with OpenCV.NET – Roman Starkov Oct 17 '09 at 19:14
7

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
  • 66,480
  • 18
  • 94
  • 155
  • 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 Jun 29 '10 at 08:32
0

This was also asked in How to get web cam images in C#? and you might find the following useful (Sorry for spamming, but this really helps answering the question):

I've just released the complete sourcecode of my Windows app CamTimer (written in .NET/C#). Download/view the complete code (with working Webcam examples) at https://github.com/johanssonrobotics/CamTimer

Happy coding!

Community
  • 1
  • 1
Fredrik Johansson
  • 3,477
  • 23
  • 37
0

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
  • 22,161
  • 4
  • 69
  • 89
0

OpenCV capture, EMGU capture and all other capture libraries I have tried
all have the same problem: You cannot go higher than 640x480 programatically
(without opening the windows video source window).

I suggest using this (which does work):
https://github.com/ofTheo/videoInput

Shachar Weis
  • 936
  • 2
  • 20
  • 44