Функция hist в matplotlib.pyplot работает очень медленно, что, по-видимому, связано с выбранной мной структурой. Я создал в Tkinter переднюю панель, которая запускает цикл управления камерой. Чтобы обеспечить оперативность цикла управления, я создал класс ImageProcessor, который собирает, обрабатывает и отображает изображения в cv2. Объект ImageProcessor выполняется в своем собственном потоке. Это работает до тех пор, пока я не пытаюсь построить гистограмму изображения.
Поскольку Tkinter не является потокобезопасным, я использую Agg в качестве бэкэнда и рисую нарисованный холст pyplot.figure. с помощью cv2. Расчет гистограммы изображения с помощью pyplot.hist занимает более 20 секунд. Самостоятельный расчет гистограммы занимает всего 0,5 секунды.
Как это проявляется? Нужно ли запускать Matplotlib из основного потока или достаточно, если с ним взаимодействует только один поток (как в моем случае)? Или в моем коде есть еще одно недоразумение?
import threading
import time
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from timeit import default_timer as timer
from datetime import timedelta
import queue
class ImageProcessor(threading.Thread):
def __init__(self):
matplotlib.use('Agg')
threading.Thread.__init__(self)
# initialize plot for histograms
self.hist_fig = plt.figure()
self.loop = True
self.continuous_acquisition_var = False
self.a = None
def run(self):
while self.loop:
self.a = np.random.uniform(low=0, high=16384, size=12320768).reshape((4096, 3008))
self.hist_fig.clf() # clear histogram plot
start = timer()
plt.hist(self.a.flatten(), bins=256, range=(0.0, 16384), fc='r', ec='r')
end = timer()
print(timedelta(seconds=end - start))
def stop(self):
self.loop = False
def ctl_loop(command):
ctl_loop_var = True
img_proc = ImageProcessor()
img_proc.daemon = True
img_proc.start()
while ctl_loop_var: # main loop
while not command.empty():
q_element = command.get()
task = q_element[0]
data = q_element[1]
func = getattr(img_proc, task)
func(data)
if task == "stop":
ctl_loop_var = False
if __name__ == '__main__':
cmd_queue = queue.Queue()
ctl = threading.Thread(target=ctl_loop, args=(cmd_queue, ))
ctl.daemon = True
ctl.start()
time.sleep(40)
cmd_queue.put(('stop', ''))
Подробнее здесь: https://stackoverflow.com/questions/786 ... yplot-hist