gpt4 book ai didi

python - 矩形的屏幕截图颜色平均

转载 作者:太空狗 更新时间:2023-10-29 20:27:45 24 4
gpt4 key购买 nike

我编写了一个快速的 Python 脚本来返回屏幕周边矩形的平均颜色。 (这里的最终目标是让 RGB LED strips 包围我的显示器,以便在看电影时产生发光效果 - 就像 this (youtube) 一样,但更有趣,因为我自己制作了它)。

我目前正在使用 autopy用于将屏幕作为位图(“屏幕截图”),获取每个像素值,以及 RGB <-> HEX 转换。

简化版:

step = 1
width = 5
height = 5

b = autopy.bitmap.capture_screen()

for block in border_block(width, height): # for each rectangle around the perimeter of my screen

R,G,B = 0,0,0
count = 0

for x in xrange(block.x_min, block.x_max, step):
for y in xrange(block.y_min, block.y_max, step):
r,g,b = autopy.color.hex_to_rgb(image.get_color(x, y))
R += r; G += g; B += b
count += 1

block.colour = "#{:06x}".format(autopy.color.rgb_to_hex(R/count,G/count,B/count))

然后我使用 matplotlib 显示 block :(配置为 5x5 block ,步长 = 1)

5x5 Screenshot

问题在于执行速度 - 因为这是对 block 中的每个像素进行循环(2560*1600 分辨率/5 = 320*512 block = 每个 block 163,840 个像素),每个 block 围绕周边(16*163,840 = 2,621,440 个循环)。总的来说,这需要 2.814 秒才能完成。

如果我增加步长值,它会加速,但还不够:(这是在边界周围使用更逼真的 15x10 block )

Step    Time (s)
1 1.35099983215
2 0.431000232697
5 0.137000083923
10 0.0980000495911
15 0.095999956131
20 0.0839998722076
50 0.0759999752045

那是因为屏幕截图本身大约需要 0.070 秒 - 这意味着我被限制为 12.8 FPS。

>>> timeit.Timer("autopy.bitmap.capture_screen()", "import autopy").timeit(100)/100
0.06874468830306966

问题:

  • 有没有更快的截取屏幕截图和平均屏幕区域的方法?

    我不太担心准确性,但希望能够以大约 30 FPS 的速度返回这些值,最好更快(20-30 毫秒)以允许串行传输开销。请记住我的屏幕分辨率是 2560*1600!

    我听说过 Python Imaging Library (PIL) ,但还没有时间研究 ImageGrab 函数的速度,但它看起来很有希望。

  • 我可以直接从 GPU 读取像素值吗?

  • 另一个想法 - 检测电影顶部/底部边缘的最佳方法是什么? (如果纵横比是宽屏,截图的顶部/底部有黑条,部分矩形是黑色的)。


使用 PIL 的 grab():

>>> timeit.Timer("ImageGrab.grab()", "from PIL import ImageGrab").timeit(100)/100
0.1099840205312789

PIL - 调整大小: (ChristopheD)

>>> timeit.Timer("PIL.ImageGrab.grab().resize((15, 10), PIL.Image.NEAREST)", "import PIL").timeit(100)/100
0.1028043677442085

>>> timeit.Timer("PIL.ImageGrab.grab().resize((15, 10), PIL.Image.ANTIALIAS)", "import PIL").timeit(100)/100
0.3267692217886088

注意:这是对上述结果的改进,但我们仍然限制在 9 FPS,或 3 FPS 且完全抗锯齿。


PIL - 最近然后调整大小:(Mark Ransom)

>>> for step in [1,2,5,10,15,20,50]:
print step, timeit.Timer("PIL.ImageGrab.grab().resize(("+str(2560/step)+", "+str(1600/step)+"), PIL.Image.NEAREST).resize((15, 10), PIL.Image.ANTIALIAS)", "import PIL.ImageGrab").timeit(100)/100

结果:

Step  Time(s)
1 0.333048412226
2 0.16206895716
5 0.117172371393
10 0.102383282629
15 0.101844097599
20 0.101229094581
50 0.100824552193

比在顶部使用 autopy 手动循环快得多,但我们仍然限制在 ~9 FPS(“步长”为 10)。

注意:这不包括所需的 RGB 到 HEX 转换


谁能想出更快的方法 - 即截取部分屏幕截图?我应该用 C 写点东西吗?

最佳答案

使用 Python 图像库。来自docs (在图像模块中):

getcolors

im.getcolors() => a list of (count, color) tuples or None

im.getcolors(maxcolors) => a list of (count, color) tuples or None

(New in 1.1.5) Returns an unsorted list of (count, color) tuples, where the count is the number of times the corresponding color occurs in the image.

Image 模块还包含一个 crop() 方法,您可以使用它来让每个矩形插入 getcolors()。您可以轻松地从中获取加权平均值。

它应该比在 python 中手动运行循环快得多。我不确定它是否足够快以供实时使用,但您会获得显着的速度提升。您也可以每秒截取几次屏幕截图,因为很有可能以 60 fps 和 10 fps 的速度向 LED 发送信号不会特别引人注目。不要将其视为“限制为 12.8 FPS”,将其视为“每 5 帧只能更新一次 LED”,这应该不会有明显差异。

编辑:如果您真的对这里的进一步优化感兴趣,我想您会发现Fastest way to take a screenshot with python on windows很有帮助。

关于python - 矩形的屏幕截图颜色平均,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10654381/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com