1

I'm trying to use matplotlib.pyplot to view a video as I process the frames. The code below displays a plot window, but the images are never drawn.

import cv2
import matplotlib.pyplot as plt  

class Viewer:
    def __init__(self, video_filename):
        self.cap = cv2.VideoCapture(video_filename)
        self.ax1 = plt.subplot(1, 2, 1)
        self.ax2 = plt.subplot(1, 2, 2)

        # Grab the first frame.
        frame = self.grabframe()
        self.im1 = self.ax1.imshow(frame)
        self.im2 = self.ax2.imshow(frame)

    def grabframe(self):
        ret, frame = self.cap.read()
        if ret:
            return frame
        else:
            print('[ERROR] grabframe failed')
            return self.grabframe()

    def update(self, frame):
        """Update the display."""
        print('[INFO] updating...')
        self.im1.set_data(frame)
        self.im2.set_data(frame)
        plt.draw()


def main():
    """Run it."""
    cli = argparse.ArgumentParser()
    cli.add_argument('-i', '--input', type=str, required=True)
    args = cli.parse_args()

    viewer = Viewer(args.input)

    while True:
        viewer.update(viewer.grabframe())

if __name__ == '__main__':
    plt.ion()
    plt.show()
    main()

The update function is definitely being called and I am sure that the frames contain image data. I tried explicitly creating a figure and adding the axis to that. I also tried fig.canvas.draw. Also I've experimented with calling plt.show() in the main function. Nothing changed in any of those cases. Why aren't the images drawn on the plot like I expect?

noel
  • 2,257
  • 3
  • 24
  • 39
  • You call `plt.show()` before `main()`. That makes no sense. – ImportanceOfBeingErnest Jan 17 '18 at 22:11
  • you should also explicitly create a `Figure` object (call it `fig`) and explicitly add the axes to that via `fig.add_subplot(...)` – Paul H Jan 17 '18 at 22:12
  • I made some updates to what I've tried. – noel Jan 17 '18 at 22:15
  • @noel show me what you tried as described in that edit – Paul H Jan 17 '18 at 22:16
  • also, remove the `cv2` requirement. no one else can run this code so it's going to be tough to troubleshoot – Paul H Jan 17 '18 at 22:17
  • @PaulH I just made all those changes again to be sure I was remembering correctly. It works now. SMH. I'll post the working code. – noel Jan 17 '18 at 22:18
  • I doubt a figure object is in any way necessary here. What is additionally not clear is how you run the script. There is an argument `-i` required, which is not passed at any point in the script. [Here](https://stackoverflow.com/questions/44598124/update-frame-in-matplotlib-with-live-camera-preview) is a working example of how to animate a cv2 video. – ImportanceOfBeingErnest Jan 17 '18 at 22:19

0 Answers0