如何在 python 中实时加速 rgb 绘图

How to speed up rgb plotting in real time in python

我被要求编写一个疯狂的想法。我们想要一个屏幕来显示它可以使用 RGB 格式和每个可用像素生成的所有可能图像。当然,我们知道这样的代码需要数百万年 运行 才能完成(甚至更多),但这仍然是我们想要做的。我有一些很好用的东西,唯一的问题是图像的绘制真的很慢...

我目前正在使用 matplotlib,为了速度我愿意尝试其他东西,但我必须承认我不熟悉其他工具并且我经常发现文档很难理解(例如 glumpy)

这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
import time
import itertools
from PyQt5 import QtWidgets 
plt.ion()
import ctypes

# Getting the screensize
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)


fig = plt.figure()

#To remove toolbar from figure
try:
     win = fig.canvas.manager.window
except AttributeError:
     win = fig.canvas.window()          
toolbar = win.findChild(QtWidgets.QToolBar) #same
toolbar.setVisible(False)                   #same
fig.canvas.manager.full_screen_toggle()     #To display the result in fullscreen

# To remove white space between axis and figure
ax = fig.add_axes([0,0,1,1]) #position: left, bottom, width, height
ax.set_axis_off()
pixel_x, pixel_y = screensize[::-1]

initial_image = np.zeros((pixel_x,pixel_y,3)).astype(np.uint8)
image = ax.imshow(initial_image, animated = True)
ch = ax.get_children()
fig.canvas.draw()

# itertools allow me to iterate over all possible image pretty efficiently
for x in itertools.product(np.arange(0,256,steps,dtype = "uint8"),repeat = pixel_y*pixel_x*3):

    x = np.fromiter(x,dtype = np.uint8) # I read that np.fromiter is quicker than np.array
    x = x.reshape(pixel_x,pixel_y,3)    # Putting everything back in an image appropriate 
                                        # format
   
    ch[-2].set_data(x)       # I try not to redraw the entire figure by only changing this
    ax.draw_artist(ch[-2])   # I redraw the artist
    fig.canvas.blit(fig.bbox)# Read online that this was quicker
    fig.canvas.flush_events()# same...



    j+=1
    if j % 10 == 0:
        print(f'{j/(time.time() - t):.2f} iterations per seconde')

所以我发现 itertools.product 的迭代速度相对较快:这部分的速度可以达到每秒 40-45 次迭代。使用 np.fromiter 将 itertools 输出转换为 numpy 数组会减慢过程的速度:它下降到每秒大约 25 次迭代。以适当的图像格式重塑结果似乎不会减慢任何速度。最后,当我用 set_data 方法和所有内容包括所有绘图时,它减慢到每秒 5-6 次交互,这真的很慢......

如果您对我如何使这个过程更有效率有任何见解,请告诉我!我们将不胜感激。谢谢

  1. 谨慎使用matplotlib

  2. 如果有人用matplotlib作图,就别看了

  3. 要显示视频,请使用openCV。要显示图像,请使用 opencv/Pillow 除非您不想在图像旁边显示任何额外的东西,例如轴

  4. 多想想自己在做什么,因为你在做的事情真的不值得做。

OPENCV 实现(333-500 FPS)

import numpy as np
import time
import itertools

import cv2


steps = 1
pixel_x, pixel_y = [3, 3]
initial_image = np.zeros((pixel_x, pixel_y, 3)).astype(np.uint8)

import time

for x in itertools.product(
    np.arange(0, 256, steps, dtype="uint8"), repeat=pixel_y * pixel_x * 3
):
    s = time.time()
    x = np.fromiter(x, dtype=np.uint8)
    x = x.reshape(pixel_x, pixel_y, 3)
    cv2.imshow("Frame", x)

    if cv2.waitKey(1) & 0xFF == ord("q"):

        break
    print("FPS: ", 1 / (time.time() - s))
cv2.destroyAllWindows()