Created
December 28, 2023 09:42
quantize an entire video
This file contains 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
import logging | |
from moviepy.editor import VideoFileClip, VideoClip, concatenate_videoclips | |
from PIL import Image | |
import numpy as np | |
from sklearn.cluster import KMeans | |
import random | |
import os | |
# Configure logging | |
logging.basicConfig(filename='script_log.log', level=logging.DEBUG) | |
# Function to apply k-means clustering to an image | |
def apply_kmeans(image, colors): | |
im_array = np.array(image) | |
reshaped_array = im_array.reshape((-1, 3)) | |
# Apply k-means clustering | |
kmeans = KMeans(n_clusters=len(colors), random_state=42) | |
labels = kmeans.fit_predict(reshaped_array) | |
# Convert labels to integer array | |
labels_int = labels.astype(int) | |
# Assign the cluster centers to the image pixels | |
segmented_image_array = np.array(colors)[labels_int].reshape(im_array.shape) | |
# Convert the numpy array back to an image | |
segmented_image = Image.fromarray(np.uint8(segmented_image_array)) | |
return segmented_image | |
# Define the colors and paths | |
def ColA(): | |
Rr = random.randint(0, 255) | |
Gg = random.randint(0, 255) | |
Bb = random.randint(0, 255) | |
return [Rr, Gg, Bb] | |
colors = [ | |
ColA(), | |
ColA(), | |
ColA(), | |
ColA(), | |
ColA(), | |
ColA(), | |
ColA(), | |
ColA(), | |
ColA() | |
] | |
input_video_path = "/home/jack/Desktop/vids/6bd83e3c-2f9f-49bc-ac9f-ee233870b241.mp4" | |
output_video_path = "junk/video_segmented.mp4" | |
# Create temporary directory | |
temp_directory = "temp_directory" | |
os.makedirs(temp_directory, exist_ok=True) | |
# Process each frame of the video | |
clip = VideoFileClip(input_video_path) | |
segmented_frames = [] | |
# Apply k-means clustering to the entire video using the same set of colors | |
# Perform clustering only once and use the same colors for all frames | |
kmeans = KMeans(n_clusters=len(colors), random_state=42) | |
for i, frame in enumerate(clip.iter_frames(fps=clip.fps)): | |
if i == 0: | |
kmeans.fit(np.array(frame).reshape((-1, 3))) | |
labels = kmeans.predict(np.array(frame).reshape((-1, 3))) | |
segmented_frame_array = np.array(colors)[labels].reshape(np.array(frame).shape) | |
segmented_frame = Image.fromarray(np.uint8(segmented_frame_array)) | |
segmented_frames.append(np.array(segmented_frame)) | |
# Define a function to generate frames for the video | |
def make_frame(t): | |
return segmented_frames[int(t * clip.fps)] | |
# Create a video clip from the segmented frames | |
logging.debug(f"Creating segmented video with {len(segmented_frames)} frames.") | |
segmented_clip = VideoClip(make_frame, duration=clip.duration) | |
# Write the segmented video to a file | |
segmented_clip.write_videofile(output_video_path, codec="libx264", audio_codec="aac", fps=clip.fps) | |
# Clean up temporary directory | |
for file_path in os.listdir(temp_directory): | |
file_path = os.path.join(temp_directory, file_path) | |
os.remove(file_path) | |
os.rmdir(temp_directory) | |
logging.info("Script execution completed.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This script uses the MoviePy library to apply k-means clustering to each frame of a video, creating a segmented video where each pixel is assigned a color from a predefined set of colors.
Here's a breakdown of the script:
logging.basicConfig(filename='script_log.log', level=logging.DEBUG)
Defining the apply_kmeans Function:
Defining the Color Generator Function (ColA):
python
def ColA():
Rr = random.randint(0, 255)
Gg = random.randint(0, 255)
Bb = random.randint(0, 255)
return [Rr, Gg, Bb]
Defining the Set of Colors:
python
colors = [
ColA(),
ColA(),
ColA(),
ColA(),
ColA(),
ColA(),
ColA(),
ColA(),
ColA()
]
Setting Input and Output Paths:
python
input_video_path = "/home/jack/Desktop/vids/6bd83e3c-2f9f-49bc-ac9f-ee233870b241.mp4"
output_video_path = "junk/video_segmented.mp4"
Creating a Temporary Directory:
python
temp_directory = "temp_directory"
os.makedirs(temp_directory, exist_ok=True)
Processing Each Frame of the Video:
python
clip = VideoFileClip(input_video_path)
segmented_frames = []
kmeans = KMeans(n_clusters=len(colors), random_state=42)
for i, frame in enumerate(clip.iter_frames(fps=clip.fps)):
if i == 0:
kmeans.fit(np.array(frame).reshape((-1, 3)))
Defining a Function to Generate Frames:
python
def make_frame(t):
return segmented_frames[int(t * clip.fps)]
Creating the Segmented Video Clip:
python
segmented_clip = VideoClip(make_frame, duration=clip.duration)
Writing the Segmented Video to a File:
python
segmented_clip.write_videofile(output_video_path, codec="libx264", audio_codec="aac", fps=clip.fps)
Cleaning Up Temporary Files:
python
for file_path in os.listdir(temp_directory):
file_path = os.path.join(temp_directory, file_path)
os.remove(file_path)
os.rmdir(temp_directory)
Logging Completion Message:
python
In summary, the script takes a video, applies k-means clustering to each frame, assigns colors from a predefined set, and generates a segmented video. The process is logged, and temporary files are cleaned up.