C# 如何显示使用 Emgu 捕获的网络摄像头图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/765107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to display webcam images captured with Emgu?
提问by ZogStriP
I'm currently working on a project that use Facial Recognition. I therefore need a way to display the webcam images to the user so he can adjust his face.
我目前正在从事一个使用面部识别的项目。因此,我需要一种向用户显示网络摄像头图像的方法,以便他可以调整自己的面部。
I've been trying a lot of things to get images from the webcam using as less CPU as possible:
我一直在尝试很多方法来使用尽可能少的 CPU 从网络摄像头获取图像:
But none of them were fine... Either way too slow or too CPU resources consuming.
但它们都不好……要么太慢,要么太消耗 CPU 资源。
Then I tried the Emgu libraryand I felt great about it. At first, I tried it in a Windows Form project and was updating the image in a Picture Box. But then, when I tried to integrate it in my WPF Project I got stuck on how to pass my image to my Image control..
然后我尝试了Emgu 库,感觉很棒。起初,我在 Windows 窗体项目中尝试了它,并且正在更新Picture Box中的图像。但是,当我尝试将它集成到我的 WPF 项目中时,我陷入了如何将我的图像传递给我的图像控件的问题上。
Right now, I've the following source code:
现在,我有以下源代码:
<Window x:Class="HA.FacialRecognition.Enroll.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Width="800" Height="600"
Loaded="Window_Loaded" Closing="Window_Closing">
<Grid>
<Image x:Name="webcam" Width="640" Height="480" >
<Image.Clip>
<EllipseGeometry RadiusX="240" RadiusY="240">
<EllipseGeometry.Center>
<Point X="320" Y="240" />
</EllipseGeometry.Center>
</EllipseGeometry>
</Image.Clip>
</Image>
</Grid>
</Window>
And the code behind:
以及背后的代码:
private Capture capture;
private System.Timers.Timer timer;
public Window1()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
capture = new Capture();
capture.FlipHorizontal = true;
timer = new System.Timers.Timer();
timer.Interval = 15;
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
using (Image<Bgr, byte> frame = capture.QueryFrame())
{
if (frame != null)
{
var bmp = frame.Bitmap;
// How do I pass this bitmap to my Image control called "webcam"?
}
}
}
private void Window_Closing(object sender, CancelEventArgs e)
{
if (capture != null)
{
capture.Dispose();
}
}
My guess was to use BitmapSource/WriteableBitmap but I did not get them working...
我的猜测是使用 BitmapSource/WriteableBitmap 但我没有让它们工作......
Thanks!
谢谢!
回答by Ankit
Image Class has got a UriSource property that you may be looking for
图像类有一个您可能正在寻找的 UriSource 属性
回答by dahlbyk
I believe you have to use interop (source):
我相信你必须使用互操作(来源):
using System.Windows.Interop;
using System.Windows.Media.Imaging;
public static ImageSource AsImageSource<TColor, TDepth>(
this Image<TColor, TDepth> image) where TColor : IColor, new()
{
return Imaging.CreateBitmapSourceFromHBitmap(image.Bitmap.GetHbitmap(),
IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
Which could be used like this:
可以这样使用:
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
using (Image<Bgr, byte> frame = capture.QueryFrame())
{
if (frame != null)
{
var bmp = frame.AsImageSource();
}
}
}
If the interop doesn't perform well enough, take a look at the source of Image.ToBitmap
and Image.get_Bitmap
to see how you could implement your own WriteableBitmap
.
如果互操作性能不够好,请查看 的来源Image.ToBitmap
并Image.get_Bitmap
了解如何实现自己的WriteableBitmap
.
回答by dahlbyk
Look on the Emgu wiki -> Tutorials -> Examples -> WPF (Windows Presentation Foundation) It contains the following code snippet to convert your IImage to a BitmapSource, which you can directly apply to your control.
查看 Emgu wiki -> Tutorials -> Examples -> WPF (Windows Presentation Foundation) 它包含以下代码片段,用于将您的 IImage 转换为 BitmapSource,您可以直接将其应用于您的控件。
using Emgu.CV; using System.Runtime.InteropServices; ...
使用 Emgu.CV;使用 System.Runtime.InteropServices; ...
/// <summary>
/// Delete a GDI object
/// </summary>
/// <param name="o">The poniter to the GDI object to be deleted</param>
/// <returns></returns>
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
/// <summary>
/// Convert an IImage to a WPF BitmapSource. The result can be used in the Set Property of Image.Source
/// </summary>
/// <param name="image">The Emgu CV Image</param>
/// <returns>The equivalent BitmapSource</returns>
public static BitmapSource ToBitmapSource(IImage image)
{
using (System.Drawing.Bitmap source = image.Bitmap)
{
IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
ptr,
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
DeleteObject(ptr); //release the HBitmap
return bs;
}
}
回答by ggarber
回答by Tom Wright
I reckon all you're looking for is this:
我想你要找的就是这个:
Image<Bgr, Byte> frame = capture.QueryFrame();
pictureBox1.Image = image.ToBitmap(pictureBox1.Width, pictureBox1.Height);
回答by femi
Try this.
尝试这个。
http://easywebcam.codeplex.com/
http://easywebcam.codeplex.com/
I used it and it was excellent..
我用过,效果很好。。
回答by JumpingJezza
If you are using WPF and MVVM here is how you would do it using EMGU.
如果您使用 WPF 和 MVVM,这里是您将如何使用EMGU。
View:
看法:
<Window x:Class="HA.FacialRecognition.Enroll.Views.PhotoCaptureView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Width="800" Height="600">
<Grid>
<Image Width="640" Height="480" Source="{Binding CurrentFrame}">
<Image.Clip>
<EllipseGeometry RadiusX="240" RadiusY="240">
<EllipseGeometry.Center>
<Point X="320" Y="240" />
</EllipseGeometry.Center>
</EllipseGeometry>
</Image.Clip>
</Image>
</Grid>
Viewmodel:
视图模型:
namespace HA.FacialRecognition.Enroll.ViewModels
{
public class PhotoCaptureViewModel : INotifyPropertyChanged
{
public PhotoCaptureViewModel()
{
StartVideo();
}
private DispatcherTimer Timer { get; set; }
private Capture Capture { get; set; }
private BitmapSource _currentFrame;
public BitmapSource CurrentFrame
{
get { return _currentFrame; }
set
{
if (_currentFrame != value)
{
_currentFrame = value;
OnPropertyChanged();
}
}
}
private void StartVideo()
{
Capture = new Capture();
Timer = new DispatcherTimer();
//framerate of 10fps
Timer.Interval = TimeSpan.FromMilliseconds(100);
Timer.Tick += new EventHandler(async (object s, EventArgs a) =>
{
//draw the image obtained from camera
using (Image<Bgr, byte> frame = Capture.QueryFrame())
{
if (frame != null)
{
CurrentFrame = ToBitmapSource(frame);
}
}
});
Timer.Start();
}
public static BitmapSource ToBitmapSource(IImage image)
{
using (System.Drawing.Bitmap source = image.Bitmap)
{
IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ptr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
DeleteObject(ptr); //release the HBitmap
return bs;
}
}
/// <summary>
/// Delete a GDI object
/// </summary>
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
//implementation of INotifyPropertyChanged, viewmodel disposal etc
}