视频素描化
闲来无事,整合了几位大佬的代码,写了一个把视频素描化的代码
流程:视频分割为单张图片,图片素描化,拼接素描图片,提取原视频音乐,与拼接的视频进行合成
下面展示一些 内联代码片
。
生成无声音素描视频
scmc=input("请输入素材名称前缀,切勿带.MP4:")
try:
# 删除之前文件,并创建空文件夹
import shutil
import os
import time
import subprocess
print("删除文件中")
try:
path = 'E:/sm'
shutil.rmtree(path) # 递归删除文件夹,即:删除非空文件夹
except:
print("文件不存在已重新创建")
path = r'E:/'
a = "sm"
os.mkdir(path + './' + a)
try:
path = 'E:/sm1'
shutil.rmtree(path) # 递归删除文件夹,即:删除非空文件夹
except:
print("文件不存在已重新创建")
path = r'E:/'
a = "sm1"
os.mkdir(path + './' + a)
print("分割视频")
# 分割视频
import cv2
cap = cv2.VideoCapture(scmc+'.mp4')
fourcc = cv2.VideoWriter_fourcc(*'XVID')
fps = cap.get(cv2.CAP_PROP_FPS)
# fps=30
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
# size=(960,544)
i = 0
while (cap.isOpened()):
i = i + 1
print("分割" + str(i - 1) + "张图片")
ret, frame = cap.read()
if ret == True:
cv2.imwrite('E:/sm/' + str(i) + '.png', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv2.destroyAllWindows()
# 数量统计
path = 'E:/sm/'
tushu = len([lists for lists in os.listdir(path) if os.path.isfile(os.path.join(path, lists))])
print("图片转素描," + "共计图片" + str(tushu) + "张")
from PIL import Image
import numpy as np
for qishi in range(1, tushu):
path1 = str(qishi) + '.png'
print("图片转素描第" + str(qishi) + "张")
a = np.asarray(Image.open(r'E:/sm/' + path1).convert('L')).astype('float')
depth = 10. # (0-100)
grad = np.gradient(a) # 取图像灰度的梯度值
grad_x, grad_y = grad # 分别取横纵图像梯度值
grad_x = grad_x * depth / 100.
grad_y = grad_y * depth / 100.
A = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.)
uni_x = grad_x / A
uni_y = grad_y / A
uni_z = 1. / A
vec_el = np.pi / 2.2 # 光源的俯视角度,弧度值
vec_az = np.pi / 4. # 光源的方位角度,弧度值
dx = np.cos(vec_el) * np.cos(vec_az) # 光源对x 轴的影响
dy = np.cos(vec_el) * np.sin(vec_az) # 光源对y 轴的影响
dz = np.sin(vec_el) # 光源对z 轴的影响
b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z) # 光源归一化
b = b.clip(0, 255)
im = Image.fromarray(b.astype('uint8')) # 重构图像
im.save(r'E:/sm1/' + path1) # 保存
# 图片拼接
print("图片拼接")
import numpy as np
import cv2
# 读取一张图片
dirfile = r'E:/sm1/1.png'
img = cv2.imread(dirfile)
size1 = img.shape
size = (size1[1], size1[0])
print("图片尺寸" + str(size))
# 完成写入对象的创建,第一个参数是合成之后的视频的名称,第二个参数是可以使用的编码器,第三个参数是帧率即每秒钟展示多少张图片,第四个参数是图片大小信息
videowrite = cv2.VideoWriter('test.mp4', -1, 30, size) # 20是帧数,size是图片尺寸
img_array = []
for filename in [r'E:\sm1\{0}.png'.format(i) for i in range(1, tushu)]:
print("拼接" + str(filename))
img = cv2.imread(filename)
if img is None:
print(filename + " is error!")
continue
img_array.append(img)
for i in range(1, tushu):
videowrite.write(img_array[i])
print('end!')
time.sleep(5)
except:
print("有问题存在,但请无视")
print("音频提取")
from moviepy.editor import *
video = VideoFileClip(scmc+'.mp4') #视频所在路径
audio = video.audio
audio.write_audiofile('1.mp3') #音频所在路径
print("请手动执行合成程序")
声音视频合成
print("视频+音频合成")
from moviepy.editor import CompositeAudioClip, VideoFileClip, AudioFileClip
videoFile = 'test.mp4' # 视频文件
video = VideoFileClip(videoFile)
videos = video.set_audio(AudioFileClip('1.mp3')) # 音频文件
videos.write_videofile('compose.mp4', audio_codec='aac') # 保存合成视频,注意加上参数audio_codec='aac',否则音频无声音