0%

python实现视频转字符

抖音上看到那种把舞蹈变成字符型的小视频,如下图那种。就一直想弄一个。参考了网上写的好多代码,自己整理了一个。

![在这里插入图片描述](https://img-blog.csdnimg.cn/2019081121230937.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3Nvbmdzb25nTA==,size_16,color_FFFFFF,t_70 =300x)

大概思路:

  1. 先将原视频分割为一张一张的图片
  2. 再将这些图片转换为字符型的
  3. 又将这些字符型的图片串成视频即可

废话不多说,完整代码如下,有注释说明,只需更改一下视频路径及其存储路径即可。

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
# -*- coding: utf-8 -*-
"""
Created on Sun Aug 11 20:55:29 2019

@author: Administrator
"""

import cv2
import os
from PIL import Image, ImageDraw, ImageFont

WIDTH = 80 #定义输出画面的宽度
HEIGHT = 45 #定义
ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ") #所用字符列表

# 将256灰度映射到70个字符上
def get_char(r, g, b, alpha=256): # alpha透明度
if alpha == 0:
return ' '
length = len(ascii_char)
gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b) # 计算灰度
unit = (256.0 + 1) / length
return ascii_char[int(gray / unit)] # 不同的灰度对应着不同的字符

#通过灰度来区分色块
#该部分以下和灰度值字符画区别所在
def PictureToChar(sourcePath,storagePath):
print("开始将图片转为字符型:")
# 循环最多读取1100张图片,自己可更改
for icount in range(1, 1100):
IMG = sourcePath+str(icount)+'.jpg' #文件路径
if os.path.exists(IMG):
im = Image.open(IMG)
#视频分割后图片的长与宽,与合成视频时要相统一,保存下来,合成字符视频时用到
sourceImage=im
WIDTH = int(im.width/6) #高度比例为原图的1/6较好,由于字体宽度
HEIGHT = int(im.height/15) #高度比例为原图的1/15较好,由于字体高度
im_txt = Image.new("RGB",(im.width,im.height),(255,255,255))
im = im.resize((WIDTH,HEIGHT),Image.NEAREST)
txt = ""
colors = []
for i in range(HEIGHT):
for j in range(WIDTH):
pixel = im.getpixel((j,i))
colors.append((pixel[0],pixel[1],pixel[2]))#记录像素颜色信息
if(len(pixel) == 4):
txt += get_char(pixel[0],pixel[1],pixel[2],pixel[3])
else:
txt += get_char(pixel[0],pixel[1],pixel[2])
txt += '\n'
colors.append((255,255,255))
dr = ImageDraw.Draw(im_txt)
font=ImageFont.load_default().font#获取字体
x=y=0
#获取字体的宽高
font_w,font_h=font.getsize(txt[1])
font_h *= 1.37 #调整后更佳
#ImageDraw为每个ascii码进行上色
for i in range(len(txt)):
if(txt[i]=='\n'):
x+=font_h
y=-font_w
dr.text([y,x],txt[i],colors[i])
y+=font_w
#输出
name = str(icount) + '.jpg'
print(name)
im_txt.save(storagePath + str(icount) + '.jpg')
return sourceImage

def charToVideo(storagePath,sourceImage):
# 设置视频编码器,这里使用使用MJPG编码器
#fourcc = cv2.VideoWriter_fourcc(*'MJPG')

#这里是mp4格式
fourcc = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')#不同视频编码对应不同视频格式(例:'I','4','2','0' 对应avi格式)

print("开始将字符型图片变为视频:")
#输出视频参数设置,包含视频文件名、编码器、帧率、视频宽高(此处参数需和字符图片大小一致)
videoWriter = cv2.VideoWriter(storagePath+'test.mp4', fourcc, 30.0, (sourceImage.width,sourceImage.height))

#循环最多读取1100张图片,自己可更改
for i in range(1, 1100):
filename = storagePath +str(i)+'.jpg'
# 判断图片是否存在
if os.path.exists(filename):
img = cv2.imread(filename=filename)
# 在一个给定的时间内(单位ms)等待用户按键触发,100ms
cv2.waitKey(100)
# 将图片写入视频中
videoWriter.write(img)
print(str(i) + '.jpg' + ' done!')
# 视频释放
videoWriter.release()
print("字符视频已成功生成!!!")

def VideoToPicture(path):
# 在当前目录下新建文件夹
folder_path = "imgbear/"
os.makedirs(folder_path)
# 进行视频的载入
vc = cv2.VideoCapture(path)
print("开始将原视频分割为图片:")
c = 0
# 判断载入的视频是否可以打开
ret = vc.isOpened()
# 循环读取视频帧
while ret:
c = c + 1
# 进行单张图片的读取,ret的值为True或者Flase,frame表示读入的图片
ret, frame = vc.read()
if ret:
# 存储为图像
cv2.imwrite(folder_path+str(c) + '.jpg', frame)
# 输出图像名称
print(folder_path+str(c) + '.jpg')
# 在一个给定的时间内(单位ms)等待用户按键触发,1ms
cv2.waitKey(1)
else:
break
# 视频释放
vc.release()
return folder_path

if __name__=='__main__':

#视频所在路径
path='C://Users//Administrator//Desktop//aa.mp4'
#存储路径,路径上的文件夹必须已经存在
storagePath='C://Users//Administrator//Desktop//1//'
sourcePath = VideoToPicture(path)
sourceImage = PictureToChar(sourcePath,storagePath)
charToVideo(storagePath,sourceImage)

最后结果如下:

在这里插入图片描述

------------- Thank you for reading -------------

Title - Artist
0:00