Alternative to taking rapid screenshots of a window
Asked Answered
M

1

7

I have a utility I'm testing with a few other people, that takes screenshots of another window and then uses OpenCV to find smaller images within that screenshot.

That's working without a problem, however, I'm trying to make it more efficient, and was wondering, rather than taking a screenshot of the window every X milliseconds, if there was a way I could "stream" the screen to my app, and then run a function against every new frame that comes through.

This is my current code:

    public static bool ContainsImage(Detection p_Detection, out long elapsed)
    {
        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();

        Image<Gray, byte> imgHaystack = new Image<Gray, byte>(CaptureApplication(p_Detection.WindowTitle));
        Image<Gray, byte> imgNeedle = new Image<Gray, byte>(p_Detection.Needle);

        if (imgHaystack.Width >= p_Detection.Settings.Resolution || imgHaystack.Height >= p_Detection.Settings.Resolution)
        {
            imgHaystack = imgHaystack.Resize(imgHaystack.Width / p_Detection.Settings.Scale, imgHaystack.Height / p_Detection.Settings.Scale, Emgu.CV.CvEnum.Inter.Area);
            imgNeedle = imgNeedle.Resize(imgNeedle.Width / p_Detection.Settings.Scale, imgNeedle.Height / p_Detection.Settings.Scale, Emgu.CV.CvEnum.Inter.Area);
        }

        if (imgNeedle.Height < imgHaystack.Height && imgNeedle.Width < imgHaystack.Width)
        {
            using (Image<Gray, float> result = imgHaystack.MatchTemplate(imgNeedle, Emgu.CV.CvEnum.TemplateMatchingType.CcoeffNormed))
            {
                result.MinMax(out double[] minValues, out double[] maxValues, out Point[] minLocations, out Point[] maxLocations);

                if (maxValues[0] > p_Detection.Settings.MatchThreshold)
                {
                    stopWatch.Stop();
                    elapsed = stopWatch.ElapsedMilliseconds;

                    imgHaystack.Dispose();
                    imgNeedle.Dispose();
                    return true;
                }
            }
        }

        stopWatch.Stop();
        elapsed = stopWatch.ElapsedMilliseconds;

        imgHaystack.Dispose();
        imgNeedle.Dispose();
        return false;
    }

I'm not entirely sure that this is the most efficient way to accomplish what I'm attempting, any help would be brilliant.

Thank you.

Maryjomaryl answered 3/6, 2018 at 18:45 Comment(0)
B
5

Maybe you can use Desktop Window Manager and DwmRegisterThumbnail?

Take a look at the following example and see if it can work for you.

It's a really fast way of streaming the image of another window, just like the preview image in the task bar. Not sure it's practical for image analysis though.

Beseem answered 8/6, 2018 at 13:36 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.