Изображение не обновляется при записи в ... странные события - PullRequest
1 голос
/ 14 марта 2012

У меня есть приложение Kinect WPF, которое берет изображения из Kinect, выполняет некоторые функции обнаружения с помощью EmguCV (AC # opencv wrapper) и отображает вывод с использованием образа WPF.

У меня было это работаетраньше, но теперь приложение отказывается обновлять изображение на экране, когда записывается источник изображения, но я не изменил способ его работы.

Изображение (называемое видео) записывается так:

video.Source = bitmapsource;

в обработчике событий colorframeready.

Это прекрасно работает, пока я не введу некоторый код opencv до того, как источник изображений будет записан.Неважно, какой источник используется, поэтому я не думаю, что это конфликт.Я сузил нарушающий код EmguCV до этой строки:

RecentKeyPoints = surfCPU.DetectKeyPointsRaw(ImageRecent, null);

, которая переходит прямо в код opencv.Стоит отметить, что:

  • ImageRecent имеет совершенно другое происхождение от битмапсорсинга, обновляющего экран.
  • Чтение видео. Источник возвращает битмапсорсор, поэтому кажется, что он пишет правильно,не обновляет экран.

Дайте мне знать, если вам нужна дополнительная информация ...

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 Ответ

1 голос
/ 23 августа 2012

Это немного поздно, но у меня была похожая проблема, и я решил поделиться своим решением.

В моем случае я обрабатывал поток глубины. Разрешение по умолчанию было 640x480, и Emgu просто не смог обработать изображение достаточно быстро, чтобы не отставать от обработчика кадров. Как только я уменьшил разрешение потока глубины до 320x240, проблема исчезла.

Я также пошел немного дальше и переместил обработку изображений в другой поток, что ускорило его (выполните поиск по ComponentDispatcher.ThreadIdle). Я до сих пор не могу сделать 640x480 с разумной частотой кадров, но, по крайней мере, изображение отображается, чтобы я мог видеть, что происходит.

...