当写入奇怪的事情时,图像不会更新

时间:2012-03-14 18:00:19

标签: c# wpf opencv emgucv

我有一个Kinect WPF应用程序,它从Kinect获取图像,使用EmguCV(A C#opencv包装器)进行一些特征检测,并使用WPF图像显示输出。

我之前有过这个工作,但应用程序现在拒绝在写入imagesource时更新屏幕图像,但我没有改变它的工作方式。

图像(称为视频)按原样写入:

video.Source = bitmapsource;

在colorframeready事件处理程序中。

这一点工作正常,直到我在写入imagesource之前引入一些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;
}

1 个答案:

答案 0 :(得分:1)

这有点晚了,但我遇到了类似的问题,并且认为我会分享我的解决方案。

在我的情况下,我正在处理深度流。默认分辨率是640x480,而Emgu只是无法足够快地处理图像以跟上frameready处理程序。一旦我将深度流分辨率降低到320x240,问题就消失了。

我也走得更远,将我的图像处理移动到另一个线程,加快了它的速度(搜索ComponentDispatcher.ThreadIdle)。我仍然无法以合理的帧速率进行640x480,但至少图像呈现所以​​我可以看到发生了什么。