2014-01-13 219 views
1

我遇到了EmguCV的问题。我使用了一个演示应用程序,并将其编辑为我的需要。 它包括以下功能:Emgucv转换<Hsv, Byte>()图片

public override Image<Gray, byte> DetectSkin(Image<Bgr, byte> Img, IColor min, IColor max) 
     { 
      Image<Hsv, Byte> currentHsvFrame = Img.Convert<Hsv, Byte>(); 
      Image<Gray, byte> skin = new Image<Gray, byte>(Img.Width, Img.Height); 
      skin = currentHsvFrame.InRange((Hsv)min,(Hsv)max); 
      return skin; 
     } 

在演示应用程序,图片来自于视频。该框架是从这样的视频中捕获:

Image<Bgr, Byte> currentFrame; 
grabber = new Emgu.CV.Capture(@".\..\..\..\M2U00253.MPG");    
      grabber.QueryFrame(); 
currentFrame = grabber.QueryFrame(); 

在我的应用程序中,图像来自microsoft kinect流。

我用下面的功能:

private void SensorColorFrameReady(object sender, ColorImageFrameReadyEventArgs e) 
     { 
      using (ColorImageFrame colorFrame = e.OpenColorImageFrame()) 
      { 
       if (colorFrame != null) 
       { 
        // Copy the pixel data from the image to a temporary array 
        colorFrame.CopyPixelDataTo(this.colorPixels); 

        // Write the pixel data into our bitmap 
        this.colorBitmap.WritePixels(
         new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight), 
         this.colorPixels, 
         this.colorBitmap.PixelWidth * sizeof(int), 
         0); 

        Bitmap b = BitmapFromWriteableBitmap(this.colorBitmap); 
        currentFrame = new Image<Bgr, byte>(b); 
        currentFrameCopy = currentFrame.Copy(); 
        skinDetector = new YCrCbSkinDetector(); 

        Image<Gray, Byte> skin = skinDetector.DetectSkin(currentFrame, YCrCb_min, YCrCb_max); 


       } 
      } 
     } 
private static System.Drawing.Bitmap BitmapFromWriteableBitmap(WriteableBitmap writeBmp) 
     { 
      System.Drawing.Bitmap bmp; 
      using (System.IO.MemoryStream outStream = new System.IO.MemoryStream()) 
      { 
       BitmapEncoder enc = new BmpBitmapEncoder(); 
       enc.Frames.Add(BitmapFrame.Create((BitmapSource)writeBmp)); 
       enc.Save(outStream); 
       bmp = new System.Drawing.Bitmap(outStream); 
      } 
      return bmp; 
     } 

现在,演示应用程序的工作,而我没有。矿给出了以下异常: exception

而且,这里的图像,包含以下内容: enter image description here

我真的不明白这一点例外。而且,现在,当我运行演示程序时,工作应用程序图像包含: enter image description here

在我眼里,这是完全一样的。我真的不明白这一点。帮助非常欢迎!

回答

1

为了方便起见,我上传你的代码参考sourceforge上页工作WPF解决方案,我已经建立:使用EMGU 64 2.42

http://sourceforge.net/projects/emguexample/files/Capture/Kinect_SkinDetector_WPF.zip/download https://sourceforge.net/projects/emguexample/files/Capture/

这是设计和测试所以在项目的Lib文件夹中你会找到引用的dll。如果您使用的是不同的版本,则需要删除当前的参考文件并将其替换为您使用的版本。

其次,项目的设计就像代码参考库中的所有项目一样,从Emgu.CV.Example文件夹构建到.. \ EMGU 2.XXX \ bin .. opencv编译库所在的全局bin目录在x86或x64的文件夹中。

如果你努力让代码工作,我可以提供所有组件,但我讨厌重新分配你已经拥有的所有opencv文件,所以让我知道你是否想要这个。

您将需要手动调整主窗口大小来显示两个图像,因为我没有花太多时间玩布局。

因此,代码...

在窗体初始化方法我检查Kinect感应器,并成立了事件处理的准备帧。我已经保留了原始的阈值和skinDetector类型,尽管我没有使用EMGU版本,我只是忘记删除它。你将需要玩阈值等。

  //// Look through all sensors and start the first connected one. 
      //// This requires that a Kinect is connected at the time of app startup. 
      //// To make your app robust against plug/unplug, 
      //// it is recommended to use KinectSensorChooser provided in Microsoft.Kinect.Toolkit (See components in Toolkit Browser). 
      foreach (var potentialSensor in KinectSensor.KinectSensors) 
      { 
       if (potentialSensor.Status == KinectStatus.Connected) 
       { 
        this.KS = potentialSensor; 
        break; 
       } 
      } 

      //If we have a Kinect Sensor we will set it up 
      if (null != KS) 
      { 
       // Turn on the color stream to receive color frames 
       KS.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30); 
       //Turn on the depth stream to recieve depth frames 
       KS.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30); 

       //Start the Streaming process 
       KS.Start(); 
       //Create a link to a callback to deal with the frames 
       KS.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(KS_AllFramesReady); 

       //We set up a thread to process the image/disparty map from the kinect 
       //Why? The kinect AllFramesReady has a timeout if it has not finished the streams will simply stop 
       KinectBuffer = new Thread(ProcessBuffer); 

       hsv_min = new Hsv(0, 45, 0); 
       hsv_max = new Hsv(20, 255, 255); 
       YCrCb_min = new Ycc(0, 131, 80); 
       YCrCb_max = new Ycc(255, 185, 135); 

       detector = new AdaptiveSkinDetector(1, AdaptiveSkinDetector.MorphingMethod.NONE); 
       skinDetector = new YCrCbSkinDetector(); 
      } 

我总是与Kinect的数据速度一个新的线程玩,但你可能要提前这一个后台工作,如果你打算做任何更重的处理,因此是更好的管理。

线程调用ProcessBuffer()方法可以忽略所有注释代码,因为这是用于显示深度图像的代码的剩余部分。我再次使用Marshall复制方法来保持速度,但要查找的是WPF中的Dispatcher.BeginInvoke,它允许从Kinect线程显示图像。这是必需的,因为我没有在主线程上处理。

 //This takes the byte[] array from the kinect and makes a bitmap from the colour data for us 
     byte[] pixeldata = new byte[CF.PixelDataLength]; 
     CF.CopyPixelDataTo(pixeldata); 
     System.Drawing.Bitmap bmap = new System.Drawing.Bitmap(CF.Width, CF.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb); 
     BitmapData bmapdata = bmap.LockBits(new System.Drawing.Rectangle(0, 0, CF.Width, CF.Height), ImageLockMode.WriteOnly, bmap.PixelFormat); 
     IntPtr ptr = bmapdata.Scan0; 
     Marshal.Copy(pixeldata, 0, ptr, CF.PixelDataLength); 
     bmap.UnlockBits(bmapdata); 
     //display our colour frame 
     currentFrame = new Image<Bgr, Byte>(bmap); 


     Image<Gray, Byte> skin2 = skinDetector.DetectSkin(currentFrame, YCrCb_min, YCrCb_max); 
     ExtractContourAndHull(skin2); 

     DrawAndComputeFingersNum(); 

     //Display our images using WPF Dispatcher Invoke as this is a sub thread. 
     Dispatcher.BeginInvoke((Action)(() => 
      { 
       ColorImage.Source = BitmapSourceConvert.ToBitmapSource(currentFrame); 
      }), System.Windows.Threading.DispatcherPriority.Render, null); 
     Dispatcher.BeginInvoke((Action)(() => 
      { 
       SkinImage.Source = BitmapSourceConvert.ToBitmapSource(skin2); 
      }), System.Windows.Threading.DispatcherPriority.Render, null); 

我希望这有助于我将在某个时候neaten了我上传的代码,

干杯

+0

非常感谢您的评论。我仍然无法解决如何解决它。当我使用你的代码时,我得到了一些我似乎无法解决的错误(可能是因为我缺乏知识)。但是,这里是我使用的代码:https://dl.dropboxusercontent.com/u/71972424/codeHandTracker.zip – Arnout

+0

我得到了您的代码工作,但它仍然给我同样的错误。 – Arnout

+0

如果有兴趣,这里是包括演示在内的完整解决方案的链接。 https://dl.dropboxusercontent.com/u/71972424/HandGestureRecognition.rar – Arnout