前言
處理視頻濾鏡之前禀酱,需要先掌握圖片濾鏡的處理控乾,如何將一張夜景圖片修改為賽博朋克的風(fēng)格剩失?
- 參考文章:Python 圖像處理:濾鏡之賽博朋克
視頻濾鏡
夜景素材
渲染效果
Python 代碼
import ffmpeg
import numpy as np
import os
from image.cyber import cyberpunk
import cv2
if __name__ == '__main__':
# 源視頻
video_path = 'night.mp4'
video_probe = ffmpeg.probe(video_path)
video_info = next((stream for stream in video_probe['streams'] if stream['codec_type'] == 'video'), None)
video_frames = int(video_info['nb_frames'])
width = int(video_info['width'])
height = int(video_info['height'])
video_input = ffmpeg.input(video_path)
in_process = (
video_input.video.output('pipe:', format='rawvideo', pix_fmt='rgb24', r=30).run_async(pipe_stdout=True)
)
# 濾鏡視頻流
tmp_path = 'night_tmp.mp4'
tmp_process = (
ffmpeg
.input('pipe:', format='rawvideo', pix_fmt='rgb24', s='{}x{}'.format(width, height), framerate=30)
.output(tmp_path, pix_fmt='yuv420p', r=30)
.overwrite_output()
.run_async(pipe_stdin=True)
)
frame_index = 1
# 視頻幀處理
while True:
in_bytes = in_process.stdout.read(width * height * 3)
if not in_bytes:
break
in_frame = (
np
.frombuffer(in_bytes, np.uint8)
.reshape([height, width, 3])
)
# 漸變式局部濾鏡視頻勘究,過渡時(shí)間 5 秒渗鬼,幀率為 30勘畔,則此處設(shè)置的值為 150
in_frame_bgr = cv2.cvtColor(in_frame, cv2.COLOR_RGB2BGR)
current_width = int(width * (frame_index / 150))
in_frame_bgr[:, 0:current_width, :] = cyberpunk(in_frame_bgr[:, 0:current_width, :])
in_frame = cv2.cvtColor(in_frame_bgr, cv2.COLOR_BGR2RGB)
tmp_process.stdin.write(
in_frame
.astype(np.uint8)
.tobytes()
)
if frame_index < 150:
frame_index += 1
# 等待異步處理完畢
tmp_process.stdin.close()
in_process.wait()
tmp_process.wait()
# 將原始視頻的音樂合并到新視頻
result_path = 'night_new.mp4'
(
ffmpeg.input(tmp_path)
.output(video_input.audio, result_path, r=30)
.run(overwrite_output=True)
)
# 刪除臨時(shí)文件
os.remove(tmp_path)