Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

update frame in matplotlib with live camera preview

I am new to both Python and Matplotlib. My computer is connected to two usb cameras, and I intend to use the subplot(1,2,1) and subplot(1,2,2) in matplotlib to plot the frames from the two camera in time series. When I do this with my code, I either get only one frame plotted or get a black screen in the plotting area.

My code look like below

#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.
like image 828
jxw Avatar asked Jun 16 '17 21:06

jxw


People also ask

How do you update the same plot in matplotlib?

We can use matplotlib to Plot live data with Matplotlib. With the help of matplotlib. pyplot. draw() function we can update the plot on the same figure during the loop.

Can matplotlib plot real time?

To create a real-time plot, we need to use the animation module in matplotlib. We set up the figure and axes in the usual way, but we draw directly to the axes, ax , when we want to create a new frame in the animation.


1 Answers

Interactive mode

One way of updating a plot in matplotlib is to use interactive mode (plt.ion()). You should then not recreate new subplots for each frame you capture, but create your plot with images once and update it afterwards.

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

Another option is of course to use matplotlib's built in FuncAnimation which is especially designed to animate plots.

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()

In order to close the window on a key press event, you may add a callback, like so

#... 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.
like image 146
ImportanceOfBeingErnest Avatar answered Sep 28 '22 00:09

ImportanceOfBeingErnest