Generate images from video with imageio
From video to frames
- From video to frames
- Frame data type
- Crop a square in the center of the image
- Plot cropped frames
- Save/load a frame
Use imageio
library to get frames out of a video. I used a sample.mp4 video as the example. Install imageio
with pip install imageio-ffmpeg
to use the video-format support of the library.
import os
import imageio
import matplotlib.pyplot as plt
os.environ["VIDEO_PATH"] = "data/2021-10-20-from-video-to-image/sample.mp4"
os.environ["IMAGE_PATH"] = "data/2021-10-20-from-video-to-image/sample_frame.jpeg"
I set 1 frame per second and the image size to be (1080, 1920)
. If the size
parameter is not specified the reader will infer from the video file.
reader = imageio.get_reader(
os.environ["VIDEO_PATH"],
fps=1,
size=(1080, 1920)
)
Get the frames out of the video:
frames = []
for i, im in enumerate(reader):
frames.append(im)
print('Mean of frame %i is %1.1f' % (i, im.mean()))
The frames are of type imageio.core.util.Array
. We can convert them to numpy array if necessary with np.array
.
frames[0].__class__
import numpy as np
image = np.asarray(im)
image.__class__
def crop_center_square(frame):
y, x = frame.shape[0:2]
min_dim = min(y, x)
start_x = (x // 2) - (min_dim // 2)
start_y = (y // 2) - (min_dim // 2)
return frame[start_y : start_y + min_dim, start_x : start_x + min_dim]
Example:
i = 0
plt.figure(figsize=(10, 10))
ax = plt.subplot(1, 2, 1)
plt.imshow(frames[i])
ax = plt.subplot(1, 2, 2)
plt.imshow(crop_center_square(frames[0]))
i = 0
plt.figure(figsize=(10, 10))
for idx, im in enumerate(frames[0:12]):
ax = plt.subplot(3, 4, idx + 1)
plt.imshow(crop_center_square(frames[idx]))
Save:
imageio.imwrite(os.environ["IMAGE_PATH"], frames[0])
Load:
image = imageio.imread(os.environ["IMAGE_PATH"])
plt.figure(figsize=(10, 10))
plt.imshow(image)