主要分为三部分,抽帧,每帧转手绘风,再将所有照片拼接成视频。
主要是第二部,大家可以尽情发挥转字符串画之类的都可以。
冲!
第一部分视频抽帧
import os
import cv2
def extract_frames(video_path, dst_folder, index, frame_num):
video = cv2.VideoCapture()
if not video.open(video_path):
print("can not open the video")
exit(1)
count = 0
frames_num = video.get(7)
# step = int(frames_num/frame_num) #if you want to gap
step = 1
while True:
_, frame = video.read()
if frame is None:
break
if count % step == 0:
save_path = "{}/{:>04d}.png".format(dst_folder, index)
cv2.imwrite(save_path, frame)
index += 1
count += 1
if (index==frames_num):
# if (index==frame_num): #if you want to gap
break
video.release()
if __name__ == '__main__':
video_path = './视频.mp4'
ims_folder = './frames'
if not os.path.exists(ims_folder):
os.makedirs(ims_folder)
index = 0
target_num = 16
extract_frames(video_path, ims_folder, index ,target_num)
第二部分每帧转手绘风
# -*- endoding: utf-8 -*-
# @ModuleName:手绘风
# @Function(功能):
# @Author : 苏穆冰白月晨
# @Time : 2021/4/22 20:13
from PIL import Image
import numpy as np
a = 1
for i in range(0,999):
i_str=str(i).zfill(4)
# img = Image.open('.\\frames\\'+ i_str +'.png')
# img = Image.open(f'.\\frames\\{i_str}.png')
a = np.array(Image.open(f'.\\frames\\{i_str}.png').convert('L')).astype('float')
depth = 10.
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_ez = np.pi / 4.
dx = np.cos(vec_el) * np.cos(vec_ez)
dy = np.cos(vec_el) * np.sin(vec_ez)
dz = np.sin(vec_el)
b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)
b = b.clip(0, 255)
im = Image.fromarray(b.astype('uint8'))
# 保存转化后的图片
im.save(f'.\\framesstr\\{i_str}.jpg')
print(i,'已完成')
这里报错不用管 这边直接用的for循环 选图片的 所以结尾会没图片
第三部整合图片成视频
import os
from PIL import Image
import cv2
if __name__ == '__main__':
ims_folder = './framesstr'
video_path = './out_video.mp4'
ims_path_list = os.listdir(ims_folder)
ims_path_list.sort()
fps = 30
im_path = os.path.join(ims_folder, ims_path_list[0])
im_size = Image.open(os.path.join(ims_folder, ims_path_list[0])).size
fourcc = cv2.VideoWriter_fourcc(*"MP4V")
videoWriter = cv2.VideoWriter(video_path, fourcc, fps, im_size)
for i, im_path in enumerate(ims_path_list):
im_path = os.path.join(ims_folder, im_path)
frame = cv2.imread(im_path)
videoWriter.write(frame)
print(im_path)
videoWriter.release()
print('finish')
操作的视频这边默认命名为 视频.MP4 大家可以自行在源码修改。抽帧的图片所在文件夹为 frames 将抽帧图片转化为手绘风的图片文件夹为 framesstr 。
更多精彩----》 公众号:python网络小蜘蛛