基于python opencv的字符画视频合成

字符画的原理就是先将图像转换为灰度图,再将图像每个像素灰度值映射到相应的字符上,当所有灰度值转化完成后就是字符文本了。而要实现字符视频的生成就需要以下步骤,将原视频进行抽帧,对每一帧图像进行转换,将转换后的字符文本转换为图像,最后将字符图像合成视频。

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()

效果图
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sijianwuxian/article/details/126824916