2012-03-14 45 views
1

我有一個Kinect WPF應用程序,從Kinect中獲取圖像,使用EmguCV(AC#opencv包裝)進行一些功能檢測,並使用WPF顯示輸出圖片。圖片不會更新,當寫到..奇怪的事情

我已經有過這個工作,但應用程序現在拒絕更新屏幕圖像時,圖像源被寫入,但我沒有改變它的工作方式。在colorframeready事件處理程序

video.Source = bitmapsource;

圖像(稱爲視頻)被寫入到這樣。

這工作正常,直到我介紹一些opencv代碼之前的圖像源被寫入。使用什麼來源並不重要,所以我不認爲這是衝突。我已經收窄違規EmguCV代碼這一行:

RecentKeyPoints = surfCPU.DetectKeyPointsRaw(ImageRecent, null);

可跳轉直接進入OpenCV的代碼。值得注意的是:

  • ImageRecent與更新屏幕的bitmapsource有着完全不同的起源。
  • 閱讀video.Source返回bitmapsource,所以它似乎是正確寫入,只是沒有更新屏幕。

讓我知道,如果你想要的任何詳細信息...

void nui_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e) 
{ 
    // Checks for a recent Depth Image 
    if (!TrackingReady) return; 

    // Stores image 
    using (ColorImageFrame colorImageFrame = e.OpenColorImageFrame()) 
    { 
     if (colorImageFrame != null) 
     { 
      if (FeatureTracker.ColourImageRecent == null) 
       //allocate the first time 
       FeatureTracker.ColourImageRecent = new byte[colorImageFrame.PixelDataLength]; 

      colorImageFrame.CopyPixelDataTo(FeatureTracker.ColourImageRecent); 
     } 
     else return; 
    } 

    FeatureTracker.FeatureDetect(nui); 

    //video.Source = FeatureTracker.ColourImageRecent.ToBitmapSource(); 
    video.Source = ((Bitmap)Bitmap.FromFile("test1.png")).ToBitmapSource(); 

    TrackingReady = false; 
} 

public Bitmap FeatureDetect(KinectSensor nui) 
{ 
    byte[] ColourClone = new byte[ColourImageRecent.Length]; 
    Array.Copy(ColourImageRecent, ColourClone, ColourImageRecent.Length); 
    Bitmap test = (Bitmap)Bitmap.FromFile("test1.png"); 

    test.RotateFlip(RotateFlipType.RotateNoneFlipY); 

    Image<Gray, Byte> ImageRecent = new Image<Gray, byte>(test); 
    SURFDetector surfCPU = new SURFDetector(2000, false); 
    VectorOfKeyPoint RecentKeyPoints; 
    Matrix<int> indices; 
    Matrix<float> dist; 
    Matrix<byte> mask; 
    bool MatchFailed = false; 

    // extract SURF features from the object image 
    RecentKeyPoints = surfCPU.DetectKeyPointsRaw(ImageRecent, null); 
    //Matrix<float> RecentDescriptors = surfCPU.ComputeDescriptorsRaw(ImageRecent, null, RecentKeyPoints); 
    //MKeyPoint[] RecentPoints = RecentKeyPoints.ToArray(); 

    // don't feature detect on first attempt, just store image details for next attempt 
    #region 
    /* 
    if (KeyPointsOld == null) 
    { 
     KeyPointsOld = RecentKeyPoints; 
     PointsOld = RecentPoints; 
     DescriptorsOld = RecentDescriptors; 
     return ImageRecent.ToBitmap(); 
    } 
    */ 
    #endregion 

    // Attempt to match points to their nearest neighbour 
    #region 
    /* 
    BruteForceMatcher SURFmatcher = new BruteForceMatcher(BruteForceMatcher.DistanceType.L2F32); 
    SURFmatcher.Add(RecentDescriptors); 
    int k = 5; 
    indices = new Matrix<int>(DescriptorsOld.Rows, k); 
    dist = new Matrix<float>(DescriptorsOld.Rows, k); 
    */ 

    // Match features, provide the top k matches 
    //SURFmatcher.KnnMatch(DescriptorsOld, indices, dist, k, null); 

    // Create mask and set to allow all features 
    //mask = new Matrix<byte>(dist.Rows, 1); 
    //mask.SetValue(255); 
    #endregion 

    //Features2DTracker.VoteForUniqueness(dist, 0.8, mask); 

    // Check number of good maches and for error and end matching if true 
    #region 
    //int nonZeroCount = CvInvoke.cvCountNonZero(mask); 
    //if (nonZeroCount < 5) MatchFailed = true; 
    /* 
    try 
    { 
     nonZeroCount = Features2DTracker.VoteForSizeAndOrientation(RecentKeyPoints, KeyPointsOld, indices, mask, 1.5, 20); 
    } 
    catch (SystemException) 
    { 
     MatchFailed = true; 
    } 
    if (nonZeroCount < 5) MatchFailed = true; 

    if (MatchFailed) 
    { 
     return ImageRecent.ToBitmap(); 
    } 
    */ 
    #endregion 

    //DepthMapColourCoordsRecent = CreateDepthMap(nui, DepthImageRecent); 
    //PointDist[] FeatureDistances = DistanceToFeature(indices, mask, RecentPoints); 
    //Image<Rgb,Byte> rgbimage = ImageRecent.Convert<Rgb, Byte>(); 
    //rgbimage = DrawPoints(FeatureDistances, rgbimage); 

    // Store recent image data for next feature detect. 
    //KeyPointsOld = RecentKeyPoints; 
    //PointsOld = RecentPoints; 
    //DescriptorsOld = RecentDescriptors; 

    //CreateDepthMap(nui, iva); 
    //rgbimage = CreateDepthImage(DepthMapColourCoordsRecent, rgbimage); 

    // Convert image back to a bitmap 
    count++; 
    //Bitmap bitmap3 = rgbimage.ToBitmap(); 
    //bitmapstore = bitmap3; 

    //bitmap3.Save("test" + count.ToString() + ".png"); 

    return null; 
} 
+0

你可以在源代碼控制提交中做一個差異嗎? – 2012-03-14 19:45:13

+0

我可以,但我不認爲這會有所幫助,因爲Microsoft更改了kinect API,導致了很多更改。但是這部分代碼沒有改變。 如果你註釋掉上面的surfCPU方法調用,它會起作用,但是如果它沒有被註釋掉,它不會。即使是關於代碼的一部分如何影響.net中不相關部分的一般答案,作爲正確方向上的一點, – aforward 2012-03-14 19:57:12

+0

顯示您的代碼更好會有所幫助。在任何情況下,只要開始移除代碼塊並用模擬對象替換它們,直到您縮小它的範圍。 – 2012-03-14 20:12:25

回答

1

這是一個有點晚,但我也有類似的問題,我想我會分享我的解決方案。

在我的情況下,我正在處理深度流。默認分辨率爲640x480,Emgu無法快速處理圖像以跟上幀準備處理程序。只要我將深度流分辨率降低到320x240,問題就消失了。

我還走了一步,並將我的圖像處理移到了一個不同的線程,它加快了速度(對ComponentDispatcher.ThreadIdle進行搜索)。我仍然無法以合理的幀頻進行640x480的處理,但至少可以呈現圖像,以便我可以看到發生了什麼。