使用 OpenCV 连续捕获桌面循环

Continuous capture desktop loop with OpenCV

我有以下捕获桌面并将位图转换为地图以在 OpenCVSharp 中进行边缘处理的方法:

static void Main(string[] args)
{
    var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                   Screen.PrimaryScreen.Bounds.Height,
                                   PixelFormat.Format32bppArgb);

    var gfxScreenshot = Graphics.FromImage(bmpScreenshot);

    gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                                Screen.PrimaryScreen.Bounds.Y,
                                0,
                                0,
                                Screen.PrimaryScreen.Bounds.Size,
                                CopyPixelOperation.SourceCopy);

    Bitmap bitmap = new Bitmap(bmpScreenshot); 

    Mat src = BitmapConverter.ToMat(bitmap);
    Mat dst = new Mat();

    Cv2.Canny(src, dst, 0, 0);

    using (new Window("dst image", dst))
    {
        Cv2.WaitKey();
    }
}

我正在尝试的是实时捕获桌面不断更新 dst window

我已经尝试过一个带睡眠的 while 循环,但是 dst windows 最终变成灰色并挂起[=13​​=]

在opencvsharp中有没有更高效的捕获和转换方式?

我找到了一个 python 示例,但使用了 numpy 和 imagegrab 是否可以用 c# 实现?

import numpy as np
from PIL import ImageGrab
import cv2

def screen_record(): 
while True:
    printscreen_pil =  ImageGrab.grab()
    printscreen_numpy =   np.array(printscreen_pil.getdata(),dtype='uint8')\
    .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3)) 
    cv2.imshow('window',printscreen_numpy)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

OK 找到了一种方法可以做到这一点,但是它的吃内存我已经尝试过 src.dispose() 但仍然会破坏内存?

        static void Main(string[] args)
    {
        while(true)
        {
            Mat src = BitmapConverter.ToMat(makeScreenshot());
            Cv2.ImShow("window", src);
            Cv2.WaitKey(5000);
        }            
    }

    public static Bitmap makeScreenshot()
    {
        Bitmap screenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

        Graphics gfxScreenshot = Graphics.FromImage(screenshot);

        gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

        gfxScreenshot.Dispose();

        return screenshot;
    }

谢谢

抱歉我迟到的回答,但我刚刚看到问题并自己解决了它:

你必须在你的 while 循环中 运行 一个 WaitKey,因为否则 windows(或者谁做过这个 :))无法处理图像,所以只需添加:

Cv2.WaitKey(milis)