【问题标题】:EMGU with C# WPFEMGU 与 C# WPF
【发布时间】:2013-05-11 21:44:34
【问题描述】:

我正在尝试遵循以下教程,但使用 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' 

任何想法我做错了什么?

【问题讨论】:

  • 来吧,阅读你正在使用的东西的文档,错误也很清楚。
  • 我不知道 EMGU 是什么,但 WPF 不关心 System.Drawing 的东西,也不会使用它。如果您希望在 WPF 中实现任何目标,请从您的所有项目中删除对 System.Drawing.dll 的所有引用并重新开始。

标签: c# wpf image opencv emgucv


【解决方案1】:

你可以得到一个ImageSource from a Bitmap(浪费但你已经有ToBitmap()),或者你可以实现直接转换。

【讨论】:

  • 您好,我认为您误解了这个问题。我正在尝试显示存储在 EMGU (OpenCV) 图像中的图像,而不是显示文件中的图像。
  • 当你看起来有路的时候,你为什么要尝试这样做?
  • 你知道OpenCV是什么,EMGU是什么吗?我正在尝试测试是否能够在开始更改之前显示 EMGU 图像。
  • @Gravy:你可以显示几乎任何东西,你只需要相应地转换它,如果你使用外国格式将没有快捷方式,除非你想做 EMGU->Bitmap->ImageSource ,因为 Bitmap->ImageSource 是众所周知的。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    问题已解决。转换图像:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        对于 EmguCV 的 v4.4 版本,添加 Emgu.CV.Bitmap nuget 包后,您可以使用 image.ToBitmap() 函数将 Image 与 .NetStandard 中的 System.Drawing.Bitmap 相互转换。

        请注意,对于非 Windows 平台,System.Drawing.Bitmap 需要安装原生 gdi+ 才能工作。

        【讨论】:

          猜你喜欢
          • 2021-04-13
          • 1970-01-01
          • 2011-06-13
          • 1970-01-01
          • 1970-01-01
          • 2017-12-05
          • 2023-03-04
          • 1970-01-01
          • 2011-04-26
          相关资源
          最近更新 更多