我刚开始用pyglet编程。opencv的视频捕获流输出BGR numpy数组,大多数在线教程/解决方案使用数组.tostring()或数组.tobyte()出租pyglet.image.ImageData文件构造纹理。它可以工作,但转换相对较慢,每帧30毫秒。然后我开始尝试ctypes数组:
import pyglet
import numpy as np
import cv2
from threading import Thread
stream = cv2.VideoCapture(0)
stream.set(cv2.CAP_PROP_FPS, 30)
_, frame_raw = stream.read()
SCREEN_HEIGHT, SCREEN_WIDTH, NCOLOR = frame_raw.shape
window = pyglet.window.Window(SCREEN_WIDTH, SCREEN_HEIGHT)
fps_display = pyglet.clock.ClockDisplay()
def get_from_stream():
global frame_raw
while True:
_, frame_raw = stream.read()
thread_get_from_stream = Thread(target=get_from_stream)
thread_get_from_stream.daemon = True
thread_get_from_stream.start()
@window.event
def on_draw():
window.clear()
# image = pyglet.image.ImageData(SCREEN_WIDTH, SCREEN_HEIGHT, 'BGR', frame_raw[:, ::-1, :].tobytes(), -SCREEN_WIDTH * 3) # flip horizontally
image = pyglet.image.ImageData(SCREEN_WIDTH, SCREEN_HEIGHT, 'BGR', np.ctypeslib.as_ctypes(frame_raw[:, ::-1, :].ravel()), -SCREEN_WIDTH * 3) # flip as well
# image = pyglet.image.ImageData(SCREEN_WIDTH, SCREEN_HEIGHT, 'BGR', np.ctypeslib.as_ctypes(frame_raw[:, ::-1, :].copy().ravel()), -SCREEN_WIDTH * 3) # copy and flip
# image = pyglet.image.ImageData(SCREEN_WIDTH, SCREEN_HEIGHT, 'BGR', np.ctypeslib.as_ctypes(frame_raw.ravel()), -SCREEN_WIDTH * 3) # no flip
image.blit(0, 0)
fps_display.draw()
pyglet.clock.schedule_interval(lambda x: None, 1/30.)
pyglet.app.run()
请参见中的四条线。带有frame_raw[:, ::-1, :].tobytes()
的第一行的工作速度约为20FPS。第二个奇怪的是,在黑屏和图像之间有很多交替的闪烁,在闪烁的过程中有些图像被翻转,有些没有!我认为这与如何在较低的级别上查看视图有关,但是当我使用第三行的copy()时,情况就和从未发生过copy一样!当我使用第四行时,没有奇怪的翻转问题,但是闪烁仍然存在。你知道吗
我尝试在配置中禁用double_buffer
,并将其传递给窗口的构造函数,但没有起到任何作用。你知道吗
怎么回事?你知道吗
更新:
与Dan Mašek讨论。锁定:
import pyglet
import numpy as np
import cv2
from threading import Thread, Lock
stream = cv2.VideoCapture(0)
stream.set(cv2.CAP_PROP_FPS, 30)
_, frame_raw = stream.read()
SCREEN_HEIGHT, SCREEN_WIDTH, NCOLOR = frame_raw.shape
window = pyglet.window.Window(SCREEN_WIDTH, SCREEN_HEIGHT)
fps_display = pyglet.clock.ClockDisplay()
lock_stream = Lock()
def get_from_stream():
global frame_raw
while True:
with lock_stream:
_, frame_raw = stream.read()
thread_get_from_stream = Thread(target=get_from_stream)
thread_get_from_stream.daemon = True
thread_get_from_stream.start()
@window.event
def on_draw():
window.clear()
with lock_stream:
# image = pyglet.image.ImageData(SCREEN_WIDTH, SCREEN_HEIGHT, 'BGR', frame_raw[:, ::-1, :].tobytes(), -SCREEN_WIDTH * 3)
image = pyglet.image.ImageData(SCREEN_WIDTH, SCREEN_HEIGHT, 'BGR', np.ctypeslib.as_ctypes(frame_raw[:, ::-1, :].ravel()), -SCREEN_WIDTH * 3)
# image = pyglet.image.ImageData(SCREEN_WIDTH, SCREEN_HEIGHT, 'BGR', np.ctypeslib.as_ctypes(frame_raw.ravel()), -SCREEN_WIDTH * 3)
image.blit(0, 0)
fps_display.draw()
pyglet.clock.schedule_interval(lambda x: None, 1/30.)
pyglet.app.run()
目前没有回答
相关问题 更多 >
编程相关推荐