EMGU 与 C# WPF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16596915/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:48:50  来源:igfitidea点击:

EMGU with C# WPF

c#wpfimageopencvemgucv

提问by Gravy

I'm trying to follow the following tutorial but using WPF instead of Win Forms:

我正在尝试遵循以下教程,但使用 WPF 而不是 Win Forms:

A Basic Program

基本程序

WPF doesn't use PictureBox, instead it uses Image.

WPF 不使用PictureBox,而是使用Image.

So here goes trying to load an Image.

所以这里尝试加载一个Image.

XAML

XAML

<Image x:Name="srcImg" Width="400" Height="300"></Image>

CS Attempt 1:

CS 尝试 1:

Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
srcImg.Source = My_Image.ToBitmap();

Error Message

错误信息

Cannot implicitly convert type 'System.Drawing.Bitmap' 
to 'System.Windows.Media.ImageSource'

CS Attempt 2:

CS 尝试 2:

Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
srcImg.Source = new BitmapImage(My_Image);

Error Message

错误信息

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' 

Any ideas what I am doing wrong?

任何想法我做错了什么?

回答by Gravy

Problem Solved. To convert the image:

问题解决了。要转换图像:

Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
srcImg.Source = BitmapSourceConvert.ToBitmapSource(myImage);

BitmapSourceConvert class:

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

回答by cap7

If you want to use Emgu CV with WPF, you should consider doing a user control with the Emgu's picturebox (this control only works with win forms) and then use it with WindowsFormsHost.

如果你想在 WPF 中使用 Emgu CV,你应该考虑用 Emgu 的图片框做一个用户控件(这个控件只适用于 win 表单),然后将它与 WindowsFormsHost 一起使用。

回答by H.B.

You can get an ImageSourcefrom a Bitmap(wasteful but you already have ToBitmap()), or you can implement a direct conversion.

您可以ImageSource从 aBitmap获取(浪费,但您已经有了ToBitmap()),或者您可以实现直接转换。

回答by 0xaryan

Copy BitmapSourceConverter.csfrom %installfolder%/Emgu/emgucv-windesktop x.x.x/Emgu.CV.WPFand add to your project to convert to BitmapSource. It is the complete version:

复制BitmapSourceConverter.cs%installfolder%/Emgu/emgucv-windesktop x.x.x/Emgu.CV.WPF,并添加到您的项目转换成的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));
         }
      }
   }
}