Skip to content

Commit

Permalink
Make video conversion more memory-efficient
Browse files Browse the repository at this point in the history
  • Loading branch information
YvesSchoenberg committed Nov 20, 2023
1 parent 3e25c0d commit 88ecc9b
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 25 deletions.
4 changes: 2 additions & 2 deletions python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "robologs-ros-utils"
version = "0.1.1a67"
version = "0.1.1a72"
description = "robologs-ros-utils is an open source library of containerized data transformations for the robotics and drone communities"
authors = ["roboto.ai <[email protected]>"]
license = "Apache-2.0"
Expand All @@ -12,7 +12,7 @@ numpy = "^1.23.1"
tqdm = "^4.64.1"
bagpy = "^0.5"
click = "^8.1.3"
opencv-python = "^4.5.0.0"
opencv-python-headless = "^4.5.0.0"
rosbags = "^0.9.13"
rosbags-image = "0.9.1"
pydantic = "^1.10.2"
Expand Down
39 changes: 16 additions & 23 deletions python/robologs_ros_utils/sources/ros1/ros_img_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,46 +61,39 @@ def convert_image_to_cv2(msg):

def create_video_from_images(input_path, output_path, output_name="video.mp4", frame_rate=12, resize=None):
"""
Creates a video from a collection of images stored in a specified directory.
Args:
input_path (str): Directory where the input images are stored.
output_path (str): Directory where the output video will be saved.
output_name (str): Name of the output video file. Defaults to 'video.mp4'.
frame_rate (int): Frame rate of the output video. Defaults to 12.
resize (float, optional): Factor by which to resize the images. If None, images are not resized.
Returns:
None
Creates a video from a collection of images stored in a specified directory, more memory-efficiently.
"""
img_array = []
output_video_path = os.path.join(output_path, output_name)
output_video_path_temp = os.path.join(output_path, "temp.mp4")

img_list = sorted(glob.glob(os.path.join(input_path, "./*.jpg")))

img_list = sorted(glob.glob(os.path.join(input_path, "*.jpg")))
if not img_list:
img_list = sorted(glob.glob(os.path.join(input_path, "./*.png")))
img_list = sorted(glob.glob(os.path.join(input_path, "*.png")))

if not img_list:
print("No images found in the specified directory.")
return

# Initialize VideoWriter with the properties of the first image
first_img = cv2.imread(img_list[0])
if resize:
first_img = cv2.resize(first_img, (0, 0), fx=resize, fy=resize, interpolation=cv2.INTER_LANCZOS4)

height, width = (first_img.shape[0], first_img.shape[1]) if len(first_img.shape) == 3 else first_img.shape
size = (width, height)
out = cv2.VideoWriter(output_video_path_temp, cv2.VideoWriter_fourcc(*"mp4v"), frame_rate, size)

# Process and write each image individually
for filename in img_list:
img = cv2.imread(filename)
if resize:
img = cv2.resize(img, (0, 0), fx=resize, fy=resize, interpolation=cv2.INTER_LANCZOS4)

out.write(img)

height, width = (img.shape[0], img.shape[1]) if len(img.shape) == 3 else img.shape
size = (width, height)
img_array.append(img)

out = cv2.VideoWriter(output_video_path_temp, cv2.VideoWriter_fourcc(*"mp4v"), frame_rate, size)

for i in range(len(img_array)):
out.write(img_array[i])
out.release()

# Using FFmpeg to convert the temporary video to final format
subprocess.call(["ffmpeg", "-i", output_video_path_temp, "-vcodec", "libx264", "-y", output_video_path])
os.remove(output_video_path_temp)

0 comments on commit 88ecc9b

Please sign in to comment.