如何在 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 次交互,这真的很慢......
如果您对我如何使这个过程更有效率有任何见解,请告诉我!我们将不胜感激。谢谢
谨慎使用matplotlib
如果有人用matplotlib作图,就别看了
要显示视频,请使用openCV。要显示图像,请使用 opencv/Pillow 除非您不想在图像旁边显示任何额外的东西,例如轴
多想想自己在做什么,因为你在做的事情真的不值得做。
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()
我被要求编写一个疯狂的想法。我们想要一个屏幕来显示它可以使用 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 次交互,这真的很慢......
如果您对我如何使这个过程更有效率有任何见解,请告诉我!我们将不胜感激。谢谢
谨慎使用matplotlib
如果有人用matplotlib作图,就别看了
要显示视频,请使用openCV。要显示图像,请使用 opencv/Pillow 除非您不想在图像旁边显示任何额外的东西,例如轴
多想想自己在做什么,因为你在做的事情真的不值得做。
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()