C#中的网络摄像头使用

22

我正在使用C#编写一个程序来连接摄像头并对其进行一些图像处理。

我有一个可以使用win32 API(avicap32.dll)连接到摄像头并向其发送消息以将其发送到剪贴板的工作应用程序。问题是,尽管在画图中可以访问,但从程序中读取它会导致空指针。

这是我用于连接摄像头的代码:

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

这是我用来复制图像到剪贴板的方法:

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

为了缩短代码,我删除了一些错误检查。

6个回答

17

最近我开始在这个领域进行一些业余工作。

我们决定使用OpenCV库和opencvdotnet包装器。它支持从网络摄像头捕获帧:

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

如果你正在进行图像处理,可以使用OpenCV的图像处理算法,这些算法已经包装在OpenCVDotNet.Algs程序集中。

如果你决定选择这条路,请确保安装OpenCV 1.0版本(如果你正在使用Vista 64位系统,则要将其安装到"c:\program files\opencv",或者从正确的目录中使用"mklink OpenCV 'c:\program files (x86)\OpenCV`"来安装,否则opencvdotnet不会安装)。


谢谢!我在抱怨微软出现神秘错误后,选择了这种方法,安装了 Visual C++ 2005 Express,现在它工作得很好 :) 为什么可再发行程序包不起作用,任何人都猜不透... - Elva
4
OpenCV.NET的维护活动不再非常积极,如果您在使用OpenCV.NET时遇到困难,请尝试使用Emgu CV。 - Roman Starkov

7
有两种方法可以将相机数据导入应用程序,分别是DirectShow和WIA。Microsoft建议使用WIA,WIA的接口相对简单易懂。我基于以前的工作创建并发布了一个开源的WIA桌面库
然而,在某些情况下,WIA过于简单了。例如,如果要调整相机属性(如帧率、分辨率等),则WIA无法胜任。Microsoft已弃用DirectShow,但他们并没有给我们任何替代方案来完全取代它的功能。我发现它在所有现有平台上仍然能正常工作(因为它非常深入人心),所以我想不到支持会很快消失。

在SourceForge上有一个非常好的DirectShow库。唯一的“问题”是它真的很复杂,这源于DShow本身就非常复杂和令人困惑的事实。有许多包装器可以做的事情并不容易解决,但是它们确实提供了许多常见用例的示例,例如显示视频或捕获帧。如果您想添加叠加层或插入其他过滤器,它可以完成,但请注意这一点并不简单明了。


实际上,DirectShow 是现在使用 Windows Vista 和 7 的方式,而且它远未被弃用,最新的 Windows 版本中仍在添加新功能。 - Jonas

2

0

0

OpenCV捕获、EMGU捕获以及我尝试过的所有其他捕获库都有同样的问题:你不能在程序中编程地超过640x480(不打开Windows视频源窗口)。

我建议使用这个(它确实有效):
https://github.com/ofTheo/videoInput


0
你尝试过 Clipboard.GetImage() 吗?你也可以尝试使用各种 Clipboard.Contains*() 方法来查看剪贴板中数据的存储格式。

我已经尝试了那个,但它还是返回 null。 - Elva

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接