File size: 5,303 Bytes
c1ae314
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
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)