2025年7月8日火曜日

Creating animations using frames in Python

Creating animations using frames in Python is a common task, especially for visualizing data, creating simple games, or generating GIFs/videos from a sequence of images. Here are the main approaches and libraries you can use:

1. Matplotlib (for data visualization and dynamic plots)

Matplotlib's animation module is excellent for animating plots and figures. It works by redrawing parts of a plot for each frame.

Key Concepts:

  • FuncAnimation: This is the most common method. You define a function that updates the plot for each frame, and FuncAnimation calls this function repeatedly.

  • ArtistAnimation: If you have a pre-computed list of Artist objects (e.g., Line2D, Image), you can use ArtistAnimation to display them sequentially.

Example using FuncAnimation (animating a sine wave):

Python
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np

# Set up the figure and axes
fig, ax = plt.subplots()
line, = ax.plot([], [], 'r-')  # An empty line to be updated

ax.set_xlim(0, 2 * np.pi)
ax.set_ylim(-1.1, 1.1)

# Initialization function: plot the background of each frame
def init():
    line.set_data([], [])
    return line,

# Animation function: this is called sequentially
def animate(i):
    x = np.linspace(0, 2 * np.pi, 100)
    y = np.sin(x + i * 0.1)  # Shift the sine wave for animation
    line.set_data(x, y)
    return line,

# Create the animation
# interval: delay between frames in ms
# blit: optimize drawing by only redrawing what has changed
ani = animation.FuncAnimation(fig, animate, init_func=init,
                              frames=200, interval=50, blit=True)

plt.title('Sine Wave Animation')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')

# To save the animation (requires ffmpeg installed):
# ani.save('sine_wave.mp4', writer='ffmpeg', fps=30)

plt.show()

To save animations from Matplotlib, you'll often need ffmpeg installed on your system. You can usually install it via your system's package manager (e.g., sudo apt-get install ffmpeg on Ubuntu, brew install ffmpeg on macOS).

2. PIL (Pillow) (for creating GIFs from images)

If you have a series of images (frames) and want to combine them into an animated GIF, Pillow (a fork of PIL) is the go-to library.

Steps:

  1. Load each image into a Pillow Image object.

  2. Store these Image objects in a list.

  3. Use the save() method of the first Image object, passing the append_images argument with the rest of the frames.

Example (creating a GIF from a sequence of image files):

Python
from PIL import Image
import os

# Create some dummy image files for demonstration
# In a real scenario, you would have your pre-rendered frames
if not os.path.exists('frames'):
    os.makedirs('frames')

for i in range(10):
    img = Image.new('RGB', (100, 100), color=(i * 20, 0, 255 - i * 20))
    img.save(f'frames/frame_{i:02d}.png')

# List of image file paths
image_paths = [f'frames/frame_{i:02d}.png' for i in range(10)]

images = []
for file_path in image_paths:
    try:
        img = Image.open(file_path)
        images.append(img)
    except FileNotFoundError:
        print(f"Warning: Frame not found at {file_path}")
        continue

if not images:
    print("No images found to create GIF.")
else:
    # Save as GIF
    # duration: delay between frames in milliseconds
    # loop: 0 means infinite loop
    images[0].save(
        'animation.gif',
        save_all=True,
        append_images=images[1:],
        duration=150,  # 150 milliseconds per frame
        loop=0
    )
    print("GIF created: animation.gif")

# Clean up dummy images (optional)
import shutil
if os.path.exists('frames'):
    shutil.rmtree('frames')

3. OpenCV (cv2) (for video creation and real-time processing)

OpenCV is a powerful library for computer vision tasks, including video processing. You can use it to create video files (e.g., MP4, AVI) from a series of images.

Steps:

  1. Define video parameters: filename, codec, frames per second (fps), and frame size.

  2. Create a cv2.VideoWriter object.

  3. Loop through your image frames, read each one, and write it to the video writer.

  4. Release the VideoWriter object.

Example (creating an MP4 video from a sequence of images):

Python
import cv2
import os
from PIL import Image # Used here just to generate some dummy frames

# Create some dummy image files for demonstration
if not os.path.exists('frames_cv'):
    os.makedirs('frames_cv')

width, height = 300, 200
for i in range(20):
    img_pil = Image.new('RGB', (width, height), color=(0, i * 10, 255 - i * 10))
    img_pil.save(f'frames_cv/frame_{i:02d}.png')

image_folder = 'frames_cv'
video_name = 'animation_opencv.mp4'

images = [img for img in os.listdir(image_folder) if img.endswith(".png")]
images.sort() # Ensure frames are in order

if not images:
    print("No images found to create video.")
else:
    # Read the first image to get dimensions
    first_frame = cv2.imread(os.path.join(image_folder, images[0]))
    height, width, layers = first_frame.shape

    fps = 10  # Frames per second
    fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Codec for .mp4, use 'XVID' for .avi

    video = cv2.VideoWriter(video_name, fourcc, fps, (width, height))

    for image in images:
        img_path = os.path.join(image_folder, image)
        frame = cv2.imread(img_path)
        video.write(frame)

    video.release()
    cv2.destroyAllWindows()
    print(f"Video created: {video_name}")

# Clean up dummy images (optional)
import shutil
if os.path.exists('frames_cv'):
    shutil.rmtree('frames_cv')

Important notes for OpenCV:

  • You need to install it: pip install opencv-python.

  • Codecs (fourcc) can be tricky. 'mp4v' is a common one for .mp4 files, 'XVID' for .avi. The available codecs depend on your OpenCV installation and system.

Choosing the Right Method:

  • Matplotlib: Best for animating data plots directly from Python. If your "frames" are generated by numerical calculations and represented as plots, this is the way to go.

  • Pillow: Ideal for combining pre-existing image files into an animated GIF. It's lightweight and perfect for web animations or small looping graphics.

  • OpenCV: Powerful for creating more complex video files from image sequences, especially if you need to perform image processing on the frames before writing them, or if you need specific video formats and higher quality output.

No matter which method you choose, the core idea of frame-based animation remains: create or load a series of individual images (frames) and then display them in sequence with a specific delay to create the illusion of movement.

0 件のコメント:

コメントを投稿