otterb February 2016

Fast Python plotting library to draw plots directly on 2D numpy array image buffer?

I often draw 2D plots directly on 2D numpy array image buffer coming from opencv webcam stream using opencv drawing functions. And, I send the numpy array to imshow and video writer to monitor and create a video.

import cv2
import numpy as np

cap = cv2.VideoCapture(0)
ret, frame = cap.read()  # frame is a 2D numpy array w640 h480
h,w,_ = frame.shape # (480,640,3)
x = np.arange(w)

writer = cv2.VideoWriter( 'out.avi', cv2.cv.FOURCC('D','I','V','3'),
            fps=30, frameSize=(w,h), isColor=True )

while True:
    ret, frame = cap.read()  # frame is a 2D numpy array w640 h480

    B = frame[:,:,0].sum(axis=0)
    B = h - h * B / B.max()
    G = frame[:,:,1].sum(axis=0)
    G = h - h * G / G.max()
    R = frame[:,:,2].sum(axis=0)
    R = h - h * R / R.max()

    pts = np.vstack((x,B)).astype(np.int32).T
    cv2.polylines(frame, [pts], isClosed=False, color=(255,0,0))
    pts = np.vstack((x,G)).astype(np.int32).T
    cv2.polylines(frame, [pts], isClosed=False, color=(0,255,0))
    pts = np.vstack((x,R)).astype(np.int32).T
    cv2.polylines(frame, [pts], isClosed=False, color=(0,0,255))

    writer.write(frame)

    cv2.imshow('frame', frame)
    key = cv2.waitKey(33) & 0xFF # for 64 bit PC
    if key in 27: # ESC key
        break

cap.release()
writer.release()

enter image description here

This works great but I wonder if I can do more stuff like what matplotlib can do such as axes, ticks, grid, title, bar graphs etc without rolling out my own plotting library based on basic cv2 drawing functions, which will be possible but I don't want reinventing the wheel.

Looking into https://wiki.python.org/moin/NumericAndScientific/Plotting, there are so many plotting libraries. So, I feel that one of them might alrea

Answers


Felipe Lema February 2016

So, if I'm getting this right, you want:

  • Plot conceptual figures (paths, polygons), with out-of-the-box indicators (axes, enclosing plots automagically) over an image
  • Video dump and hopefully realtime streaming.

If so, I'd recommend using matplotlib with moviepy.

Indeed doing savefig to stream video is not the best way, but you can make these two work rather easily.

Including small example from the link above for the record (mind licenses):

import matplotlib.pyplot as plt
import numpy as np
from moviepy.video.io.bindings import mplfig_to_npimage
import moviepy.editor as mpy

# DRAW A FIGURE WITH MATPLOTLIB

duration = 2

fig_mpl, ax = plt.subplots(1,figsize=(5,3), facecolor='white')
xx = np.linspace(-2,2,200) # the x vector
zz = lambda d: np.sinc(xx**2)+np.sin(xx+d) # the (changing) z vector
ax.set_title("Elevation in y=0")
ax.set_ylim(-1.5,2.5)
line, = ax.plot(xx, zz(0), lw=3)

# ANIMATE WITH MOVIEPY (UPDATE THE CURVE FOR EACH t). MAKE A GIF.

def make_frame_mpl(t):
    line.set_ydata( zz(2*np.pi*t/duration))  # <= Update the curve
    return mplfig_to_npimage(fig_mpl) # RGB image of the figure

animation =mpy.VideoClip(make_frame_mpl, duration=duration)
animation.write_gif("sinc_mpl.gif", fps=20)

Post Status

Asked in February 2016
Viewed 2,418 times
Voted 14
Answered 1 times

Search




Leave an answer