EMGU with C# WPF
本文关键字:WPF with EMGU | 更新日期: 2023-09-27 18:13:53
我正在尝试遵循以下教程,但使用WPF而不是Win Forms:
A Basic Program
WPF不使用PictureBox
,而是使用Image
。
所以这里尝试加载一个Image
。
XAML
<Image x:Name="srcImg" Width="400" Height="300"></Image>
CS尝试1:
Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
srcImg.Source = My_Image.ToBitmap();
错误消息Cannot implicitly convert type 'System.Drawing.Bitmap'
to 'System.Windows.Media.ImageSource'
CS尝试2:
Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
srcImg.Source = new BitmapImage(My_Image);
错误消息Error 1 The best overloaded method match for 'System.Windows.Media.Imaging.BitmapImage.BitmapImage(System.Uri)' has some invalid arguments
Error 2 Argument 1: cannot convert from 'Emgu.CV.Image<Emgu.CV.Structure.Bgr,byte>' to 'System.Uri'
你知道我做错了什么吗?
问题解决。转换图像:
Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
srcImg.Source = BitmapSourceConvert.ToBitmapSource(myImage);
BitmapSourceConvert类:
public static class BitmapSourceConvert
{
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
public static BitmapSource ToBitmapSource(IImage image)
{
using (System.Drawing.Bitmap source = image.Bitmap)
{
IntPtr ptr = source.GetHbitmap();
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
ptr,
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
DeleteObject(ptr);
return bs;
}
}
}
对于EmguCV的v4.4版本,一旦您添加了Emgu.CV.Bitmap nuget包,您可以转换Image<TColor,>使用image.ToBitmap()函数在。net standard中转换System.Drawing.Bitmap。
请注意,对于非windows平台,System.Drawing.Bitmap需要安装本地gdi+才能工作。
您可以从Bitmap
(浪费,但您已经有ToBitmap()
)中获得ImageSource
,或者您可以实现直接转换。
如果你想使用Emgu CV与WPF,你应该考虑做一个用户控件与Emgu的图片框(这个控件只适用于win窗体),然后使用它与WindowsFormsHost。
从%installfolder%/Emgu/emgucv-windesktop x.x.x/Emgu.CV.WPF
复制BitmapSourceConverter.cs
并添加到您的项目中以转换为BitmapSource。这是完整的版本:
//----------------------------------------------------------------------------
// Copyright (C) 2004-2017 by EMGU Corporation. All rights reserved.
//----------------------------------------------------------------------------
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Emgu.CV;
using Emgu.CV.CvEnum;
namespace Emgu.CV.WPF
{
public static class BitmapSourceConvert
{
/// <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;
}
}
public static Mat ToMat(BitmapSource source)
{
if (source.Format == PixelFormats.Bgra32)
{
Mat result = new Mat();
result.Create(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 4);
source.CopyPixels(Int32Rect.Empty, result.DataPointer, result.Step*result.Rows, result.Step);
return result;
} else if (source.Format == PixelFormats.Bgr24)
{
Mat result = new Mat();
result.Create(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 3);
source.CopyPixels(Int32Rect.Empty, result.DataPointer, result.Step * result.Rows, result.Step);
return result;
}
else
{
throw new Exception(String.Format("Convertion from BitmapSource of format {0} is not supported.", source.Format));
}
}
}
}