EmguCv TypeInitializationException Thrown by EmguC

2019-05-31 16:06发布

问题:

Let me start off by saying that I have indeed followed many tutorials such as the one located on EmguCv's main site in their entirety but get a TypeInitializationException thrown.

Now, listen closely because here comes the extremely weird part. I'll start by saying that there are three "levels" of my problem, however, the code in all "levels" is EXACTLY the same without even the slightest of change. This would naturally point to that I have a reference or linkage problem, but again I've attempted multiple attempts following different tutorials but to no avail.

Level 1 (this level produces a TypeInitializationException)
I create a new project, properly reference everything and such, then write my code in this new project. Upon debug, I get that exception thrown and my program exits. Here's a link to a picture of the problem: http://prntscr.com/uychc

Level 2 (this level runs completely fine and no exception is thrown)
In this level, I pretty much located one of EmguCv's example projects (VideoSurveilance in this case) then delete the default code and copy and paste all of my code in there. After adding a few more references that I needed, the program works fine. I cant post more than 3 links, but you'll have to trust me that the video picture displays correctly.

Level 3 (this level does not throw an exception but warns me of a "first chance" of one)
In this level, I copy and paste my whole Level 2 project into a different directory. After finding and relinking missing files/references, I am able to run the program but the pictures do not show and I get a "A first chance exception of type "System.TypeInitializationException" occurred in Emgu.CV.dll warning. http://prntscr.com/uycmn

I currently run Windows 7 x64 (yes I changed build options to x64 and x64 .dlls) and am running EmguCv 2.4.9 and 2.4.2 (tested on both) and Visual Studios 2010 and 2012 (tested on both).

Here's the code for what it may be worth:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    //using System.Threading.Tasks;
    using System.Windows.Forms;

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    using Microsoft.Kinect;
    using Emgu.CV;
    using Emgu.CV.CvEnum;
    using Emgu.CV.Structure;
    using Emgu.CV.UI;
    using System.IO;

    namespace VideoSurveilance
    {
       public partial class VideoSurveilance : Form
       {
            KinectSensor sensor;
            WriteableBitmap depthBitmap;
            WriteableBitmap colorBitmap;
            DepthImagePixel[] depthPixels;
            byte[] colorPixels;

            int blobCount = 0;

          public VideoSurveilance()
          {
             InitializeComponent();

          }

          private void VideoSurveilance_Load(object sender, System.EventArgs e)
          {
              foreach (var potentialSensor in KinectSensor.KinectSensors)
              {
                  if (potentialSensor.Status == KinectStatus.Connected)
                  {
                      this.sensor = potentialSensor;
                      break;
                  }
              }


              if (null != this.sensor)
              {

                  this.sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
                  this.sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
                  this.colorPixels = new byte[this.sensor.ColorStream.FramePixelDataLength];
                  this.depthPixels = new DepthImagePixel[this.sensor.DepthStream.FramePixelDataLength];
                  this.colorBitmap = new WriteableBitmap(this.sensor.ColorStream.FrameWidth, this.sensor.ColorStream.FrameHeight, 96.0, 96.0, PixelFormats.Bgr32, null);
                  this.depthBitmap = new WriteableBitmap(this.sensor.DepthStream.FrameWidth, this.sensor.DepthStream.FrameHeight, 96.0, 96.0, PixelFormats.Bgr32, null);



                  WriteableBitmap bitmap;
                  bitmap = new WriteableBitmap(this.sensor.DepthStream.FrameWidth, this.sensor.DepthStream.FrameHeight, 96.0, 96.0, PixelFormats.Bgr32, null);



                  byte[] retVal = new byte[bitmap.PixelWidth * bitmap.PixelHeight * 4];
                  bitmap.CopyPixels(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight), retVal, bitmap.PixelWidth * 4, 0);

                  Bitmap b = new Bitmap(bitmap.PixelWidth, bitmap.PixelHeight);
                  int k = 0;
                  byte red, green, blue, alpha;
                  for (int i = 0; i < bitmap.PixelWidth; i++)
                  {
                      for (int j = 0; j < bitmap.PixelHeight && k < retVal.Length; j++)
                      {
                          alpha = retVal[k++];
                          blue = retVal[k++];
                          green = retVal[k++];
                          red = retVal[k++];

                          System.Drawing.Color c = new System.Drawing.Color();
                          c = System.Drawing.Color.FromArgb(alpha, red, green, blue);

                          b.SetPixel(i, j, c);
                      }
                  }


                  Image<Bgr, Byte> temp = new Image<Bgr, byte>(b);



                  this.ibOriginal.Image = temp;

                  this.sensor.AllFramesReady += this.sensor_AllFramesReady;

                  try
                  {
                      this.sensor.Start();
                  }
                  catch (IOException)
                  {
                      this.sensor = null;
                  }
              }
          }


          private void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
          {
              blobCount = 0;
              BitmapSource depthBmp = null;
              Image<Bgr, Byte> openCVImg;
              using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
              {
                  using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
                  {
                      if (depthFrame != null)
                      {

                          blobCount = 0;
                          if (colorFrame != null)
                          {
                              byte[] pixels = new byte[colorFrame.PixelDataLength];
                              colorFrame.CopyPixelDataTo(pixels);

                              int stride = colorFrame.Width * 4;
                              BitmapSource color = BitmapImage.Create(colorFrame.Width, colorFrame.Height, 96, 96, PixelFormats.Bgr32, null, pixels, stride);
                              openCVImg = new Image<Bgr, byte>(color.ToBitmap());
                          }
                          else
                          {
                              return;
                          }

                          Image<Gray, byte> gray_image;

                          using (MemStorage stor = new MemStorage())
                          {
                              gray_image = openCVImg.InRange(new Bgr(0, 0, 150), new Bgr(200, 200, 255));

                              gray_image = gray_image.SmoothGaussian(9);

                              CircleF[] circles = gray_image.HoughCircles(new Gray(100),
                                                                          new Gray(50),
                                                                          2,
                                                                          gray_image.Height / 4,
                                                                          10,
                                                                          400)[0];

                              foreach (CircleF circle in circles)
                              {
                                  CvInvoke.cvCircle(openCVImg,
                                                    new System.Drawing.Point(Convert.ToInt32(circle.Center.X), Convert.ToInt32(circle.Center.Y)),
                                                    3,
                                                    new MCvScalar(0, 255, 0),
                                                    -1,
                                                    LINE_TYPE.CV_AA,
                                                    0);

                                  openCVImg.Draw(circle,
                                                 new Bgr(System.Drawing.Color.Red),
                                                 3);
                              }
                          }
                          ibOriginal.Image = openCVImg;
                          ibProcessed.Image = gray_image;

                      }
                  }



              }
          }


       }
    }

using System;
using System.Globalization;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Kinect;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Emgu.CV;

namespace VideoSurveilance
{
    public static class Helper
    {

        private const int MaxDepthDistance = 4000;
        private const int MinDepthDistance = 850;
        private const int MaxDepthDistanceOffset = 3150;

        public static BitmapSource SliceDepthImage(this DepthImageFrame image, int min = 20, int max = 1000)
        {
            int width = image.Width;
            int height = image.Height;

            //var depthFrame = image.Image.Bits;
            short[] rawDepthData = new short[image.PixelDataLength];
            image.CopyPixelDataTo(rawDepthData);

            var pixels = new byte[height * width * 4];

            const int BlueIndex = 0;
            const int GreenIndex = 1;
            const int RedIndex = 2;

            for (int depthIndex = 0, colorIndex = 0;
                depthIndex < rawDepthData.Length && colorIndex < pixels.Length;
                depthIndex++, colorIndex += 4)
            {

                // Calculate the distance represented by the two depth bytes
                int depth = rawDepthData[depthIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;

                // Map the distance to an intesity that can be represented in RGB
                var intensity = CalculateIntensityFromDistance(depth);

                if (depth > min && depth < max)
                {
                    // Apply the intensity to the color channels
                    pixels[colorIndex + BlueIndex] = intensity; //blue
                    pixels[colorIndex + GreenIndex] = intensity; //green
                    pixels[colorIndex + RedIndex] = intensity; //red                    
                }
            }

            return BitmapSource.Create(width, height, 96, 96, PixelFormats.Bgr32, null, pixels, width * 4);
        }




        public static byte CalculateIntensityFromDistance(int distance)
        {
            // This will map a distance value to a 0 - 255 range
            // for the purposes of applying the resulting value
            // to RGB pixels.
            int newMax = distance - MinDepthDistance;
            if (newMax > 0)
                return (byte)(255 - (255 * newMax
                / (MaxDepthDistanceOffset)));
            else
                return (byte)255;
        }


        public static System.Drawing.Bitmap ToBitmap(this BitmapSource bitmapsource)
        {
            System.Drawing.Bitmap bitmap;
            using (var outStream = new MemoryStream())
            {
                // from System.Media.BitmapImage to System.Drawing.Bitmap
                BitmapEncoder enc = new BmpBitmapEncoder();
                enc.Frames.Add(BitmapFrame.Create(bitmapsource));
                enc.Save(outStream);
                bitmap = new System.Drawing.Bitmap(outStream);
                return bitmap;
            }
        }


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

    }
}

I sincerely thank anyone who even attempts to help me and hope that anyone with similar problems can benefit from this long question.

回答1:

Found 'brute force' solution:

you have to put the "cvextern.dll" file into your build directory (x64, debug, release, or whatever) manually.

this does the job. I can't believe I spent a whole day trying to figure this out.



回答2:

As Oliver said you, your problem is very similar to this one : EmguCV TypeInitializationException The exception is thrown by an impossibility to access some dll as opencv_highgui220.dll. In CvInvoke you will find DLLImports, maybe you should insert a break point and observe what it comes.

I suppose you have already read this from emgu website