使用实时相机预览更新 matplotlib 中的帧
Posted
技术标签:
【中文标题】使用实时相机预览更新 matplotlib 中的帧【英文标题】:update frame in matplotlib with live camera preview 【发布时间】:2017-11-19 18:07:20 【问题描述】:我是 Python 和 Matplotlib 的新手。我的计算机连接到两个 USB 摄像头,我打算使用 matplotlib 中的 subplot(1,2,1) 和 subplot(1,2,2) 以时间序列绘制来自两个摄像头的帧。当我使用我的代码执行此操作时,我要么只绘制一帧,要么在绘图区域出现黑屏。
我的代码如下所示
#import
import cv2
import matplotlib.pyplot as plt
#Initiate the two cameras
cap1 = cv2.VideoCapture(0)
cap2 = cv2.VideoCapture(1)
#Capture the frames from camera 1 and 2 and display them over time using matplotlib
while True:
#grab frame from camera 1 and 2
ret1,frame1 = cap1.read()
ret2,frame2 = cap2.read()
plt.subplot(1,2,1), plt.imshow(cv2.cvtColor(frame1,cv2.COLOR_BGR2RGB))
plt.subplot(1,2,2), plt.imshow(cv2.cvtColor(frame2,cv2.COLOR_BGR2RGB))
#draw the plot
plt.show(False)
#Result is black screen. If plt.show() is called, I see the frames but then it freezes.
【问题讨论】:
这不是您问题的直接答案,但如果您愿意放弃使用 matplotlib,请考虑以下事项:***.com/questions/5089927/… 感谢您的评论。我实际上已经看到了您提到的功能。这里的目的是在相机视图中放置一些对象,因此,在正确放置对象的同时能够实时查看图像至关重要。用 matplotlib 不能做到这一点真的是真的吗? 【参考方案1】:交互模式
在 matplotlib 中更新绘图的一种方法是使用交互模式 (plt.ion()
)。
然后,您不应为捕获的每一帧重新创建新的子图,而是使用图像创建一次图,然后再更新它。
import cv2
import matplotlib.pyplot as plt
def grab_frame(cap):
ret,frame = cap.read()
return cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
#Initiate the two cameras
cap1 = cv2.VideoCapture(0)
cap2 = cv2.VideoCapture(1)
#create two subplots
ax1 = plt.subplot(1,2,1)
ax2 = plt.subplot(1,2,2)
#create two image plots
im1 = ax1.imshow(grab_frame(cap1))
im2 = ax2.imshow(grab_frame(cap2))
plt.ion()
while True:
im1.set_data(grab_frame(cap1))
im2.set_data(grab_frame(cap2))
plt.pause(0.2)
plt.ioff() # due to infinite loop, this gets never called.
plt.show()
FuncAnimation
当然,另一种选择是使用 matplotlib 内置的 FuncAnimation
,它专门用于动画绘图。
import cv2
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def grab_frame(cap):
ret,frame = cap.read()
return cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
#Initiate the two cameras
cap1 = cv2.VideoCapture(0)
cap2 = cv2.VideoCapture(1)
#create two subplots
ax1 = plt.subplot(1,2,1)
ax2 = plt.subplot(1,2,2)
#create two image plots
im1 = ax1.imshow(grab_frame(cap1))
im2 = ax2.imshow(grab_frame(cap2))
def update(i):
im1.set_data(grab_frame(cap1))
im2.set_data(grab_frame(cap2))
ani = FuncAnimation(plt.gcf(), update, interval=200)
plt.show()
为了在按键事件上关闭窗口,你可以添加一个回调,像这样
#... other code
ani = FuncAnimation(plt.gcf(), update, interval=200)
def close(event):
if event.key == 'q':
plt.close(event.canvas.figure)
cid = plt.gcf().canvas.mpl_connect("key_press_event", close)
plt.show()
# code that should be executed after window is closed.
【讨论】:
这个真的很有帮助。是否有任何可能性允许用户在不使用 CTRL + C 键的情况下按下一个键来退出 while True:... 循环?这是为了允许执行脚本中的下一行。我已经尝试过 cv2.waitkey,但它似乎没有帮助 您到底想要发生什么?所以用户按下键'Q'然后?窗户应该关闭还是应该保持打开状态?你在哪个环境下运行这个?作为脚本? 我正在使用 Python 在 Windows 计算机上运行它。当用户按下 'q' 键时,窗口应该关闭并退出 while 循环。现在我已经将我的代码修改为 while True: frame1 = grab_frame(cap1) im1.set_data(frame1) im2.set_data(frame1) plt.pause(0.1) k = cv2.waitKey(1) & 0xFF if k==ord ('q'): break 但是在运行代码时,当我在键盘上输入 q 时没有任何反应。cv2.waitKey(1)
是一个 opencv 命令,在使用 matplotlib 时不起作用。你有什么理由想按一个键而不是点击窗口的 X 来关闭它?
我不知道 cv2.waitKey 不适用于 matplotlib。按下 X 并关闭窗口很好,但我想退出 while 循环并继续我的 python 脚本。现在,当点击 X 时,还会阻止脚本在 while 循环之外运行后续行。无论如何要继续在while循环之外运行后续行?以上是关于使用实时相机预览更新 matplotlib 中的帧的主要内容,如果未能解决你的问题,请参考以下文章