首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在60fps+中将所有屏幕像素读取到python numpy数组中

如何在60fps+中将所有屏幕像素读取到python numpy数组中
EN

Stack Overflow用户
提问于 2018-07-10 00:43:27
回答 1查看 1.8K关注 0票数 2

第一次在这样的网站上提问。

我正在尝试找到一种快速阅读屏幕的方法(60fps+)。将屏幕截图到numpy是一种快速的方法,但不能与之匹配。对于像素,这个问题有一个很好的答案:Most efficient/quickest way to parse pixel data with Python?

我试着将GetPixel改成这个BMP的长格式,但这将它减少到了5fps:

代码语言:javascript
复制
t1 = time.time()
count = 0

width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
while count < 1000:
    hwin = win32gui.GetDesktopWindow()
    hwindc = win32gui.GetWindowDC(hwin)
    srcdc = win32ui.CreateDCFromHandle(hwindc)

    memdc = srcdc.CreateCompatibleDC()

    bmp = win32ui.CreateBitmap()
    bmp.CreateCompatibleBitmap(srcdc, width, height)
    memdc.SelectObject(bmp)

    memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY)
    bmpinfo = bmp.GetInfo()
    bmpInt = bmp.GetBitmapBits(False)

    count +=1
t2 = time.time()
tf = t2-t1
it_per_sec = int(count/tf)
print (str(it_per_sec) + " iterations per second")

我在youtube上看了一段视频,视频中一个人在C#上工作,他说GetPixel会打开和关闭内存,这就是为什么在每个单独的像素上做GetPixel会有很多开销。他建议锁定整个数据字段,然后才能获取像素。我不知道该怎么做,所以任何帮助都将不胜感激。(编辑:此链接可能指向该Unsafe Image Processing in Python like LockBits in C# )

还有另一种方法可以获取位图的内存地址,但我不知道如何处理它。这里的逻辑是,我应该能够从这一点将内存读取到任何numpy数组中,但我一直无法做到这一点。

任何其他快速阅读屏幕的选项也将不胜感激。

必须有一种方法,GPU知道在每个位置绘制哪些像素,这意味着必须在这里的某个存储库或数据流,我们可以利用。

另外,为什么会有高速的要求?我正在开发已经有很多开销的工作自动化工具,我希望优化屏幕数据流来帮助项目的这一部分。

EN

回答 1

Stack Overflow用户

发布于 2018-07-10 03:35:44

下面的代码使用MSS,如果将其修改为不显示输出,则1080p的输出可以达到44fps。https://python-mss.readthedocs.io/examples.html#opencv-numpy

代码语言:javascript
复制
import time

import cv2
import mss
import numpy


with mss.mss() as sct:
    # Part of the screen to capture
    monitor = {'top': 40, 'left': 0, 'width': 800, 'height': 640}

    while 'Screen capturing':
        last_time = time.time()

        # Get raw pixels from the screen, save it to a Numpy array
        img = numpy.array(sct.grab(monitor))

        # Display the picture
        #cv2.imshow('OpenCV/Numpy normal', img)

        # Display the picture in grayscale
        # cv2.imshow('OpenCV/Numpy grayscale',
        #            cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY))

        print('fps: {0}'.format(1 / (time.time()-last_time)))

        # Press "q" to quit
        if cv2.waitKey(25) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break

但仍然不完美,因为它不是60fps+,如果可能的话,使用来自GPU的原始重新打包的缓冲区将是更好的解决方案。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51250350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档