【发布时间】:2019-09-18 14:59:56
【问题描述】:
我正在尝试重现我在艺术博物馆看到的实时视频狭缝扫描效果。
程序使用 opencv-python 保存来自网络摄像头的最后 480 帧的缓冲区,然后将每帧中的一行像素组合成单个图像。我编写了产生预期效果的代码,但运行速度比我想要的要慢一些。如何以最有效的方式同时使用 python 列表和 numpy 数组来优化算法?
请注意,填充缓冲区需要 10 秒左右才能看到视频效果。
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
# originally tried to use numpy to store the buffer
#buffer = np.zeros(shape=(480,480,640,3),dtype=np.uint8)
buffer = []
slices = []
f2 = np.zeros(shape=(480,640,3),dtype=np.uint8)
display = False
rows = np.arange(480)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
frame = cv2.flip(frame, -1) # flipping the frame to get the scan lines to move downward
# originally I tried to make the buffer like this but get a memory error
#buffer = np.roll(buffer, -1, axis=0)
#buffer[-1] = frame
# using a list of numpy arrays seems to be more efficient for storing the buffer
buffer.append(frame)
if(len(buffer) > 480):
buffer = buffer[1:]
# using a list to combine a row of pixels from each frame
# could this be optimized with numpy arrays?
for i in range(len(buffer)):
slices.append(buffer[i][i])
# convert each row to a numpy array to store final frame for display
f2[rows] = np.array(slices[::-1])
slices.clear()
cv2.imshow('frame', f2)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
我的另一个想法是重写代码以使用更少的缓冲帧并将每帧中的几行组合在一起,但如果可能的话,我想尝试使用全分辨率视频优化代码。
【问题讨论】:
-
好吧,我可以提供一些优化,首先使用渲染选项,因为您的像素几乎总是只会改变一点,它会改善渲染。比使用多线程,因此下一帧将被计算为您呈现的最后一帧。您只能存储您使用的值的一半(只是一些空间优化)。
-
感谢您的建议。我找不到任何关于渲染选项的信息。有没有办法只更新已更改的像素?你有那个链接吗?我正在努力实现多线程
-
其实现在我也找不到了,也许你可以使用
set_data和draw。您可以专门针对此主题提出另一个问题。 -
我意识到由于网络摄像头的帧率,延迟效果很慢。如果我得到 30 fps 并填充 480 帧的缓冲区,这应该需要大约 16 秒,我重写了代码以便能够处理不同大小的缓冲区以获得不同的延迟效果。例如,240 帧缓冲区将每帧的两行像素组合在一起,或者 120 帧缓冲区将每帧的 4 行像素组合在一起。如果有人感兴趣,请告诉我,我会发布更多代码。
标签: python algorithm numpy opencv