Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to taking rapid screenshots of a window

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.

like image 617
MrDKOz Avatar asked Jun 03 '18 18:06

MrDKOz


1 Answers

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.

like image 148
Andreas Zita Avatar answered Sep 28 '22 11:09

Andreas Zita