decord
decord copied to clipboard
Geting frame from .avi video file is not meeting expectations
I use decord to extract a bounch fo frames from .avi video, but it gets frame in a strange cycle. code like this:
import numpy as np
import matplotlib.pyplot as plt
import decord as de
index = 2
sample_list = [140, 141, 500]
xy_dim = 0
container_rgb = de.VideoReader("P53_pancake.avi")
mv = container_rgb.get_batch([0, 200, 500]).asnumpy()[:, :, :, :]
mv_2 = container_rgb.get_batch([750, 300, 600]).asnumpy()[:, :, :, :]
show = np.concatenate([mv[0, :, :, 0], mv_2[0, :, :, 0]], axis=1)
plt.imshow(show, cmap='coolwarm', origin='upper')
result:

Accurate Frame will use opencv lib, code like this
import numpy as np
import matplotlib.pyplot as plt
import cv2
import copy
class OpenCVContainer(object):
def __init__(self, file_path):
self.data = cv2.VideoCapture(file_path)
self.out_dtype = 'numpy'
def get_batch(self, frames_idx):
frames = []
margin = 1024
current_frame_idx = max(0, min(frames_idx) - margin)
start_frame_idx = current_frame_idx
self.data.set(cv2.CAP_PROP_POS_FRAMES, start_frame_idx)
for i in range(start_frame_idx, len(self)):
ret, img = self.data.read()
if ret:
if current_frame_idx in frames_idx:
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
frames.append(rgb_img)
else:
break
current_frame_idx += 1
if len(frames) == len(frames_idx):
break
frames = copy.deepcopy(np.stack(frames))
# self.data.release()
return frames
def __len__(self):
return int(self.data.get(cv2.CAP_PROP_FRAME_COUNT))
container_rgb = OpenCVContainer("P53_pancake.avi")
mv = container_rgb.get_batch([0, 200, 500])
mv_2 = container_rgb.get_batch([750, 300, 950])
show = np.concatenate([mv[0, :, :, 0], mv_2[2, :, :, 0]], axis=1)
plt.imshow(show, cmap='coolwarm', origin='upper')
result:

the video file are contain on this url :P53_pancake.zip
do you find the reason? I meet the same problem.
This seems to be a problem with the library itself. I circumvented this problem by changing the video format from avi to mp4