Last active
December 22, 2024 17:54
-
-
Save 709924470/7e604d79ea8662dbfcf4552299d03601 to your computer and use it in GitHub Desktop.
Companion1 3dplayer matrix generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# SPDX-License-Identifier: GPL-3.0-or-later | |
# Copyright (C) 2024 S. 'Walter' Ji | |
import cv2 | |
import numpy as np | |
import glob | |
import subprocess | |
def create_matrix_frame(image_paths, rows=5, cols=8): | |
''' | |
Generates one frame(image) of matrix with fixed resolution of 3600x4000. | |
Consisting 5 rows with 8 images of 450x800. | |
The Companion1 spec states its capable of a 40deg of viewing angle, so its 1 image per degree. | |
The naming order should be image0=left most, image39=righ tmost. | |
''' | |
# Create blank canvas | |
matrix = np.zeros((4000, 3600, 3), dtype=np.uint8) | |
# Place images in matrix | |
for idx, img_path in enumerate(image_paths): | |
if idx >= rows * cols: # Stop after 40 images | |
break | |
img = cv2.imread(img_path) | |
if img is None: | |
continue | |
# Calculate position | |
row = idx // cols | |
col = idx % cols | |
# Place image in matrix | |
matrix[row*h:(row+1)*h, col*w:(col+1)*w] = img | |
return matrix | |
def main(): | |
# Get all PNG files sorted by name | |
image_files = sorted(glob.glob("*.png")) # Assumes files are in current directory | |
if len(image_files) < 40: | |
print(f"Error: Found only {len(image_files)} PNG files. Need 40 files.") | |
return | |
# Create matrix frame | |
frame = create_matrix_frame(image_files[:40]) | |
# Save frame as temporary PNG as we are using ffmpeg | |
temp_frame = 'temp_matrix.png' | |
cv2.imwrite(temp_frame, frame) | |
# Use ffmpeg to create video | |
output_file = 'output_matrix.mp4' | |
ffmpeg_cmd = [ | |
'ffmpeg', | |
'-y', # Overwrite output file if it exists | |
'-loop', '1', # Loop the input | |
'-i', temp_frame, # Input file | |
'-c:v', 'libx265', # Use H.265 codec, otherwise 3dplayer would not recognize the file | |
'-crf', '23', # Constant Rate Factor | |
'-preset', 'medium', # Encoding preset | |
'-tag:v', 'hvc1', # Add tag for better compatibility with Apple devices | |
'-t', '1', # Duration in seconds | |
'-pix_fmt', 'yuv420p', # Pixel format | |
'-vf', 'fps=30', # Frame rate | |
output_file | |
] | |
try: | |
subprocess.run(ffmpeg_cmd, check=True) | |
print(f"Video saved as {output_file}") | |
except subprocess.CalledProcessError as e: | |
print(f"Error running ffmpeg: {e}") | |
finally: | |
# Clean up temporary file, comment out if you need the matrix image to form animation | |
import os | |
if os.path.exists(temp_frame): | |
os.remove(temp_frame) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please do notice you need to install:
opencv-python
from pip, andffmpeg
executable under yourPATH
environment variable for the script to find and execute.To use the script, place it with your image sequence(image0~39.png), and just run the script under your command line.
如果要用这个脚本的, 你需要安装
opencv-python
PATH
环境变量下的任意文件夹里使用指北: 把脚本放在你的图像序列(至少40张以 png 格式存储的图片, 图片名称升序需要按视角从左到右命名)的同文件夹下, 从命令行运行脚本即可。