C#从网络摄像头捕获图像

15

最近两天我一直在寻找使用C#从网络摄像头中捕获图像的方法。我在C#方面相当新手,我不想使用外部第三方库,所以我找到了两种不错的方法,但都好像返回几乎相同的错误。我无法让它们中的任何一个工作,所以如果您能帮助我使其中任何一种运行或协助我找到替代方法,那就太好了。

所以我找到的第一种方法是使用Windows WIA。我找到了以下代码:

CommonDialogClass dialog = new CommonDialogClass();
Device camera = dialog.ShowSelectDevice(WiaDeviceType.CameraDeviceType, true, false);
        // take the photo 
Item item = camera.ExecuteCommand(CommandID.wiaCommandTakePicture);
ImageFile image = (ImageFile)item.Transfer(FormatID.wiaFormatJPEG);
        // filename and saving 
image.SaveFile("Test.jpg");

这段代码似乎正是我要找的,但我无法运行它,因为在第二行出现了以下错误:

Exception from HRESULT: 0x80210015

我发现的第二种方法是使用Avicap32.dll并使用以下示例:

http://www.timvw.be/wp-content/code/csharp/testavicap32.zip

但我现在在处理这段代码:

Image image = ((CaptureDevice)cboDevices.SelectedItem).Capture();
image.Save(@"c:\capture.png", ImageFormat.Png);

以下异常: NullReferenceException: 对象引用未设置为对象的实例。

我认为这两种解决方案都存在问题,因为它们无法找到我的相机,但是我可以在Skype中毫无问题地使用我的相机。

4个回答

21

我尝试了多种方法,对我来说最容易的方法是使用Emgu.cv(NuGet包)。

        VideoCapture capture = new VideoCapture(); //create a camera capture
        Bitmap image = capture.QueryFrame().Bitmap; //take a picture

就是这样 (自API版本3.3.0起)

旧的API方法

        Capture capture = new Capture(); //create a camera captue
        Bitmap image = capture.QueryFrame().Bitmap; //take a picture

1
尝试过了,但现在应该使用VideoCapture而不是Capture。 - André Boonzaaijer
我同意,说实话,这个问题的标题应该重新构建以更具体。问题的主体要求一种不使用第三方库的方法。但是这个问题是唯一与C#网络摄像头图像捕获相关的问题。 - Ashitakalax
1
@Termatinator 目前它只是一个位图,因此您可以像处理任何图像一样处理它。这里有一个链接,介绍如何操作:https://dev59.com/F2cs5IYBdhLWcg3wXi1D - Ashitakalax
Emgu.cv在我尝试打开设计器时损坏了我的解决方案。 - Marcello B.
2
不要忘记释放捕获和图像。 - stefan.seeland
2
还要获取Emgu.CV.Bitmap包并使用capture.QueryFrame().ToBitmap; - Eric Bourque

12
  • WIA是用于静态图像的,它是一种“与扫描仪一起工作的API”;0x80210015WIA_S_NO_DEVICE_AVAILABLE
  • AVICAP32 API名称为“Video for Windows”,实际上已经过时和废弃了,可能还可以使用(兼容性仍然存在),但很可能会使你一事无成。

与网络摄像头一起使用的API有:

  • DirectShow
  • Media Foundation

两者都是本地API,您可能会很难直接从C#代码进行接口交互,但是使用DirectShow.NET(尤其是)和Media Foundation.NET,您可以获得托管代码的包装器。您可以在此处找到有关使用DirectShow.NET的更多信息:


答案是2-3年前的。核心库自那时以来有进步吗? - Anonymous Type
1
@AnonymousType 这个答案已经有效了约10年,如果不是更久的话,也就是说这基本上已经稳定下来了。最近的更新主要是与UWP开发相关的:Windows.Media.Capture和其他类库。这些新东西主要是在已提到的Media Foundation上进行更高级别的封装,并提供与UWP世界的接口。使用Windows内置相机UI捕获照片和视频 - Roman R.
谢谢@Roman R. 我看了那个。最终选择了OpenCV。 - Anonymous Type

1

我推荐使用Aforge.net framework

它能够实现videoCaptureDevice class,在示例项目中使用了Snapshot Maker example,可以快速创建图像捕获对话框。虽然比DirectShow Library-How to capture image using directshow library without showing the webcam live images on the PictureBox or Panel慢一些,但它是稳定的,并且是从支持设备设置视频和图像分辨率的简单方法。

我遇到的唯一问题是VideoCaptureDevice.SimulateTrigger()使用后台线程从视频源创建图像并在事件上返回图像。如果您将返回的图像放在UI线程上的winform控件上,则需要委托方法以防止跨线程问题。

从Aforge.net源中获取快照制作器项目的源代码SVN链接


1
我也成功地使用了它们,但是它们对静态图像的兼容性似乎相当低,我只测试了7台相机中的2台。我的猜测是现代相机不再使用单独的图像捕获功能,而是直接抓取视频帧,而AForge已经好几年没有更新了。 - MikeT

0
你需要安装Emgu.CV、Emgu.CV.runtime.windows和Emgu.CV.Bitmap才能使其正常工作。

目前的回答表达不够清晰。请[编辑]以添加更多细节,帮助其他人理解这如何回答了提出的问题。您可以在帮助中心找到更多有关如何撰写好回答的信息。 - undefined

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