Spaces:
Runtime error
Runtime error
import cv2 | |
from PIL import Image | |
import numpy as np | |
from rembg import remove | |
import os | |
import shutil | |
import glob | |
import moviepy.editor as mp | |
from moviepy.editor import * | |
def cv_to_pil(img): | |
return Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGRA2RGBA)) | |
def pil_to_cv(img): | |
return cv2.cvtColor(np.array(img), cv2.COLOR_RGBA2BGRA) | |
def video_to_images(video_path, images_path): | |
# Open video | |
cam = cv2.VideoCapture(video_path) | |
# Get FPS | |
fps = cam.get(cv2.CAP_PROP_FPS) | |
# Extract audio | |
clip = mp.VideoFileClip(video_path) | |
clip.audio.write_audiofile("./audio.mp3") | |
# Create folder for images | |
if not os.path.exists(images_path): | |
os.makedirs(images_path) | |
else: | |
shutil.rmtree(images_path) | |
os.makedirs(images_path) | |
# Go through frames of video | |
frameno = 0 | |
while (True): | |
ret, frame = cam.read() | |
if ret: | |
# if video is still left continue creating images | |
name = images_path + str(frameno).zfill(5) + '.png' | |
print('new frame captured... ', frameno) | |
# Save frame | |
cv2.imwrite(name, frame, [int(cv2.IMWRITE_PNG_COMPRESSION), 0]) | |
frameno += 1 | |
else: | |
break | |
# Close video | |
cam.release() | |
cv2.destroyAllWindows() | |
return fps | |
def images_to_video(images_path, video_export_path, fps): | |
# Get a list of PNG images on the "test_images" folder | |
images = glob.glob(images_path + "*.png") | |
# Sort images by name | |
images = sorted(images) | |
# Read the first image to get the frame size | |
frame = cv2.imread(images[0]) | |
height, width, layers = frame.shape | |
temp_video_path = './temp-video.mp4' | |
# Codec | |
# fourcc = cv2.VideoWriter_fourcc(*"mp4v") | |
fourcc = cv2.VideoWriter_fourcc(*'XVID') | |
# fourcc = cv2.VideoWriter_fourcc(*'MPEG') | |
# Create final video | |
video = cv2.VideoWriter(filename=temp_video_path, fourcc=fourcc, fps=fps, frameSize=(width, height)) | |
# Read each image and write it to the video | |
for i, image in enumerate(images): | |
print("Writing frame to video ", i, '/', len(images)) | |
# Read the image using OpenCV | |
frame = cv2.imread(image) | |
# Write frame to video | |
video.write(frame) | |
# Exit the video writer | |
video.release() | |
# Open final video | |
videoclip = VideoFileClip(temp_video_path) | |
# Add audio to final video | |
audioclip = AudioFileClip("./audio.mp3") | |
new_audioclip = CompositeAudioClip([audioclip]) | |
videoclip.audio = new_audioclip | |
# Save final video | |
videoclip.write_videofile(video_export_path, audio_codec='aac', codec='libx264') | |
# Delete temp files | |
os.remove(temp_video_path) | |
os.remove("./audio.mp3") | |
def motion_blur(img, distance, amount): | |
# Convert to RGBA | |
img = img.convert('RGBA') | |
# Convert pil to cv | |
cv_img = pil_to_cv(img) | |
# Generating the kernel | |
kernel_motion_blur = np.zeros((distance, distance)) | |
kernel_motion_blur[int((distance - 1) / 2), :] = np.ones(distance) | |
kernel_motion_blur = kernel_motion_blur / distance | |
# Applying the kernel to the input image | |
output = cv2.filter2D(cv_img, -1, kernel_motion_blur) | |
# Convert cv to pil | |
blur_img = cv_to_pil(output).convert('RGBA') | |
# Blend the original image and the blur image | |
final_img = Image.blend(img, blur_img, amount) | |
return final_img | |
def background_motion_blur(background, distance_blur, amount_blur): | |
# Remove background | |
subject = remove(background) | |
amount_subject = 1 | |
# Blur the background | |
background_blur = motion_blur(background, distance_blur, amount_blur) | |
# Put the subject on top of the blur background | |
subject_on_blur_background = background_blur.copy() | |
subject_on_blur_background.paste(background, (0, 0), subject) | |
# Blend the subject and the blur background | |
result = Image.blend(background_blur, subject_on_blur_background, amount_subject) | |
return result | |
def video_motion_blur(video_path, export_video_path, distance_blur, amount_blur, amount_subject): | |
# Image folder | |
images_path = './images/' | |
# Convert video to images and save FPS | |
fps = video_to_images(video_path, images_path) | |
# Create list of images | |
image_path_list = glob.glob(images_path + "*.png") | |
# Sort images by name | |
image_path_list = sorted(image_path_list) | |
# Create folder for blur images | |
blur_images_path = './blur_images/' | |
if not os.path.exists(blur_images_path): | |
os.makedirs(blur_images_path) | |
else: | |
shutil.rmtree(blur_images_path) | |
os.makedirs(blur_images_path) | |
# Go through image folder | |
count = 0 | |
for filename in image_path_list: | |
# Open image an PIL image | |
img = Image.open(filename) | |
# Motion blur image | |
blur_img = background_motion_blur(img, distance_blur, amount_blur, amount_subject) | |
# Save blurred image | |
blur_img.save(blur_images_path + str(count).zfill(5) + '.png') | |
print('motion blur', str(count), '/', len(image_path_list)) | |
count += 1 | |
# Convert blurred images to final video | |
images_to_video(blur_images_path, export_video_path, fps) | |
# Delete temp folders | |
shutil.rmtree(images_path) | |
shutil.rmtree(blur_images_path) | |