1

If I have clip and need to process each frame and then show frames (display them). I found many examples on how you can get frames of clip and then save (write) them as new video. However, I tried to iterate on each frame and then show each processed image, but the Matplotlib show only one image after the loop finished.

clip = VideoFileClip(filename)
for frame in clip.iter_frames():
    new_frame= Fun(frame)
    plt.imshow(new_frame)

update frame in matplotlib with live camera preview

I found this link but it uses frames from the camera, I need to display processes images as they received from the Fun one by one. So I don't want to save it or create a list of processed frames and then show them, I need to do it one by one.

I used the second method from the link, but it prints only 0, 0 and only shows the first frame! It seems it can't change the index to go to the next frame!

import cv2
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
index =0


inF=[]
for frames in clip.iter_frames():
    inF.append(frames)

global inF


def grab_frame():
    print(index)
    frame = inF[index]
    return cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)

#Initiate the two cameras
cap1 = clip
#create two subplots
ax1 = plt.subplot(1,2,1)

#create two image plots
im1 = ax1.imshow(grab_frame())

def update(i):
    global index
    im1.set_data(grab_frame())
    index+=1


ani = FuncAnimation(plt.gcf(), update, interval=10)
plt.show()

Could you please help me? Any hint?

Thanks

H.H
  • 281
  • 1
  • 4
  • 12
  • Did you actually try the suggestion there? I do not see any reason why reading from camera or from a video directly makes a difference. The point there is interactive plot and using plt.pause. In your case you can use framerate value for pause. For grab_frame(cap2), you just supply new_frame. – Dinesh Oct 12 '18 at 09:25
  • @Dinesh Thank you. I tried the second approach from the link. But I have the problem which I mentioned in the question. I edited it. Could you please check it? – H.H Oct 12 '18 at 11:26
  • Are you sure you're not getting any error? If it only prints `0,0` instead of a long list of numbers, the animation isn't actually running at all. So please either provide a [mcve] or at least the error message you get. – ImportanceOfBeingErnest Oct 12 '18 at 12:58
  • I don't have any error message. These numbers represent the output. – H.H Oct 13 '18 at 10:33

1 Answers1

1

This is too long for comment. So posting as answer.

I read a video file directly using a library. It is working as desired. The color BGR2RGB is working as desired and the frames are changing and plays up to last frame.

import cv2
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import skvideo.io

index =0
inF=skvideo.io.vread('test.avi')


#inF=[]
#for frames in clip.iter_frames():
 #   inF.append(frames)

global inF


def grab_frame():
    print(index)
    frame = inF[index]
    return cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)

#Initiate the two cameras
cap1 = clip
#create two subplots
ax1 = plt.subplot(1,2,1)

#create two image plots
im1 = ax1.imshow(grab_frame())

def update(i):
    global index
    im1.set_data(grab_frame())
    index+=1


ani = FuncAnimation(plt.gcf(), update, interval=10)
plt.show()

There is no issue with above code. The source of error is your video or how you read your video. Obviously, it prints 0 to 32 (no. of frames in test.avi).

Dinesh
  • 1,555
  • 1
  • 16
  • 18
  • Thanks @Dinesh Unfortunately, I got the same result of 0,0! seems that the animation doesn't work :( – H.H Oct 13 '18 at 10:34