The principle of character painting is to first convert the image into a grayscale image, and then map the grayscale value of each pixel of the image to the corresponding character. When all the grayscale values are converted, the character text is obtained. To generate a character video, the following steps are required: extract frames from the original video, convert each frame of image, convert the converted character text into an image, and finally synthesize the character image into a video.
import sys
import cv2
import numpy
from cv2 import VideoCapture
from PIL import Image, ImageFont, ImageDraw
#颜色深度映射字符表
SF2='$@B%8&WM#*oahkbdpqwmLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^'
SF3=list(SF2)
#图像处理主函数
def get_tzt(im,num):
# 字符高度和宽度不一致打印到画布上高宽比例不对,需要进行修正
HDxiuzheng = [2.125,3.3]
Width = 300 #字符宽度,对应像素多少
size = im.size #获取图像的像素并储存在size列表中
HWbili=size[1]/size[0]
Height=int(Width*HWbili/HDxiuzheng[1])
if num==1:
print("图像源宽度",size[0],"\t高度",size[1],"\n转换现宽度",Width,"\t高度",Height)
im = im.resize((Width,Height)) #修改图片尺寸
im = im.convert('L') #1获得二值图像 L获取灰度图
txt = "" #建立变量储存字符串
#嵌套for循环将图像中的每一点像素的灰度值转换为相应的字符再存储在txt变量中
for i in range(Height):
for j in range(Width):
txt += SF3[int(im.getpixel((j, i))/4.15)] #getpixel是获取图像中某一点像素的RGB颜色值
txt += '\n'
im1 = Image.new("RGB", (900,680), (255, 255, 255)) #新建空白图像
dr = ImageDraw.Draw(im1) #将图像转换为画布
font = ImageFont.truetype(r"D:\Image\Ziti\宋体.ttf",6) #获取字体文件并设置字体大小
dr.text((0, 0),txt, font=font, fill="#000000") #将文本写到画布上
return cv2.cvtColor(numpy.asarray(im1), cv2.COLOR_RGB2BGR)
#视频抽帧并将图像转为字符画,再将字符图像合成视频
def Pihe():
#待转换视频文件路径
video_path = r"D:\Image\*.mp4"
is_all_frame =False # 是否对视频的所有帧进行转换(true/false)
sta_frame = 1 # 开始帧 自定义
end_frame = 500 # 结束帧 自定义
time_interval = 1 # 时间间隔 抽帧可以不连续 自定义
# 读取视频文件
videoCapture = VideoCapture(video_path)
# 读帧
success, frame = videoCapture.read()
fps = videoCapture.get(cv2.CAP_PROP_FPS)
print('源视频帧率',int(fps))
if success:
print("视频文件加载成功")
else:
print("视频文件加载失败")
sys.exit()
#合成视频的基本参数
fps = 30 #视频每秒24帧
size = (900,680) #需要转为视频的图片的尺寸
#保存视频路径
video = cv2.VideoWriter(r"D:\Image\*.avi", cv2.VideoWriter_fourcc('M', 'P', '4', '2'), fps, size)
i = 0
j = 0
if is_all_frame:
time_interval = 1
while success:
i = i + 1
img = Image.fromarray(frame) # 完成np.array向PIL.Image格式的转换
if (i % time_interval == 0):
if is_all_frame == False:
if i >= sta_frame and i <= end_frame:
j = j + 1
video.write(get_tzt(img,j))
print('当前帧处理进度:', i)
elif i > end_frame:
break
else:
j = j + 1
video.write(get_tzt(img,j))
print('当前帧处理进度:', i)
success, frame = videoCapture.read()
#关闭相关操作
videoCapture.release()
video.release()
cv2.destroyAllWindows()
print('视频转字符进度完成')
Pihe()
renderings