これはなに
この記事では、Pythonのopencv
というライブラリを用いて、複数の画像ファイルを結合し、パラパラ漫画のような動画ファイルに変換する方法を紹介する。
画像から動画を作成する手順
最初に、必要なライブラリであるopencv
とglob
をインストールする。
pip install opencv-python
pip install opencv-python-headless
pip install glob2
次に、以下のPythonスクリプトを使って、画像を動画ファイルに変換する。このPythonスクリプトは、指定されたディレクトリ内の画像ファイルを読み込み、順番に動画へ追加する。
import cv2
import os
import glob
def create_video_from_image_folder(
image_folder: str,
output_file: str,
image_extension: str = "png",
frame_rate: int = 24,
) -> None:
"""
Create a video file from a sequence of image files in the specified folder.
Parameters
----------
image_folder : str
The path to the folder containing the image files.
output_file : str
The filename of the video file to be created.
image_extension : str, optional, default="png"
The file extension of the image files (default is "png").
frame_rate : int, optional, default=24
The desired frame rate of the output video (default is 24).
Raises
------
ValueError
If no image files are found in the specified folder.
"""
# Get a list of image file paths in the specified folder, sorted in ascending order
image_filepaths = sorted(
glob.glob(os.path.join(image_folder, f"*.{image_extension}"))
)
if not image_filepaths:
raise ValueError("No image files found.")
# Read the first image to get its dimensions (height and width)
first_image = cv2.imread(image_filepaths[0])
height, width, _ = first_image.shape
# Initialize the video writer with the specified output file,
# codec, frame rate, and dimensions
video_writer = cv2.VideoWriter(
output_file,
cv2.VideoWriter_fourcc(*"mp4v"),
frame_rate,
(width, height),
)
# Iterate over the image file paths, read each image, and write it to the video
for image_filepath in image_filepaths:
current_image = cv2.imread(image_filepath)
video_writer.write(current_image)
# Release the video writer and close the output file
video_writer.release()
print(f"Video file created: {output_file}")
# Set the required variables for creating the video
image_folder_path = "/path/to/your/image/folder"
output_video_name = "output_video.mp4"
image_file_extension = "png"
video_frame_rate = 24
# Call the function with the specified variables to create the video
create_video_from_image_folder(
image_folder_path, output_video_name, image_file_extension, video_frame_rate
)
このスクリプトを実行すると、指定したディレクトリ内のPNG画像を順番に読み込み、出力動画ファイルに追加する。動画のフレームレートはデフォルトで24fpsに設定しているが、異なるフレームレートも使用できる。
動画にテキストを追加する方法
動画作成時に、各画像に異なるテキストを追加できる。
import cv2
import os
import glob
def overlay_text_on_image(
image: cv2.Mat,
text: str,
position: tuple[int, int],
font=cv2.FONT_HERSHEY_SIMPLEX,
font_scale: float = 1,
color: tuple[int, int, int] = (255, 255, 255),
thickness: int = 2,
) -> cv2.Mat:
"""
Overlay the given text on an image at the specified position.
Parameters
----------
image : cv2.Mat
The image to overlay text on.
text : str
The text to overlay.
position : tuple[int, int]
The x and y coordinates of the text position.
font : int, optional
Font type, by default cv2.FONT_HERSHEY_SIMPLEX.
font_scale : float, optional
Font scale, by default 1.
color : tuple[int, int, int], optional
Text color in BGR format, by default (255, 255, 255).
thickness : int, optional
Text thickness, by default 2.
Returns
-------
cv2.Mat
The image with the text overlay.
"""
img_with_text = image.copy()
cv2.putText(img_with_text, text, position, font, font_scale, color, thickness)
return img_with_text
def create_video_from_images(
img_folder: str,
output_path: str,
img_format: str = "png",
fps: int = 24,
titles: list[str] | None = None,
) -> None:
"""
Create a video from images in the specified folder.
Parameters
----------
img_folder : str
The folder containing the images.
output_path : str
The path to save the output video file.
img_format : str, optional
The image file format, by default "png".
fps : int, optional
The frames per second for the output video, by default 24.
titles : list[str] | None, optional
A list of titles for each image, by default None.
Raises
------
ValueError
If no image files are found
or if the number of titles does not match the number of images.
"""
# Get image files in the specified folder and sort by filename
img_files = sorted(glob.glob(os.path.join(img_folder, f"*.{img_format}")))
if not img_files:
raise ValueError("No image files found.")
if titles is not None and len(titles) != len(img_files):
raise ValueError("Number of titles does not match the number of image files.")
frame = cv2.imread(img_files[0])
height, width, _ = frame.shape
video = cv2.VideoWriter(
output_path,
cv2.VideoWriter_fourcc(*"mp4v"), # Specify the video file codec
fps,
(width, height),
)
for index, img_file in enumerate(img_files):
frame = cv2.imread(img_file)
if titles is not None:
text = titles[index]
frame = overlay_text_on_image(
frame, text, (10, 30), font_scale=1, color=(40, 40, 40), thickness=2
)
video.write(frame)
video.release()
print(f"Video created: {output_path}")
img_folder = "/path/to/your/image/folder" # Path to the image folder
output_path = "output_video.mp4" # Name of the output video file
img_format = "png" # Image file format
fps = 24 # Frame rate
titles = [
"Title 1",
"Title 2",
"Title 3",
] # List of titles for each image. Set to None to skip adding text.
create_video_from_images(img_folder, output_path, img_format, fps, titles)
テキストの色を変更したい場合は、color
の値を変更する。