100行代码让你的代码跳起舞(视频转字符画)

思路分析

    整体步骤分为三步:

  1. 对视频进行抽帧得到图片
  2. 对图片进行处理得到字符画
  3. 按照一定顺序和一定时间在终端打印字符画实现动画效果

最终效果

 

代码实现

  • 第一步视频抽帧

# 第一步视频抽帧
def chouzhen(video_path):
    # 保存图片的路径
    savedpath = video_path.split('.')[0] + '/'
    isExists = os.path.exists(savedpath)
    if not isExists:
        os.makedirs(savedpath)
        # print('path of %s is build' % (savedpath))
    else:
        shutil.rmtree(savedpath)
        os.makedirs(savedpath)
        # print('path of %s already exist and rebuild' % (savedpath))

    # 视频帧率12
    fps = 12
    # 保存图片的帧率间隔
    count = 3

    # 开始读视频
    videoCapture = cv2.VideoCapture(video_path)
    i = 0
    j = 0
    while True:
        success, frame = videoCapture.read()
        i += 1
        if (i % count == 0):
            # 保存图片
            j += 1
            savedname = video_path.split('\\')[-1].split('.')[0] + '_' + '%04d' % j + '.jpg'
            cv2.imwrite(savedpath + savedname, frame)
            # print('image of %s is saved' % (savedname))

        if not success:
            print('抽帧完成')
            break
  • 第二步 把抽帧得到的图片集转换为字符画集

# 第二步 把抽帧得到的图片全部转化为字符画
def pic2str(video_path):
    ascil_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
    table = ('#8XOHLTI)i=+;:,. ')  # 对于灰度图像效果不错


    # 拿到保存图片的路径
    pics_path = video_path.split('.')[0]

    # 创建保存字符画的路径
    str_pic_path = video_path.split('.')[0] + '_str'
    isExists = os.path.exists(str_pic_path)
    if not isExists:
        os.makedirs(str_pic_path)
        # print('path of %s is build' % (savedpath))
    else:
        shutil.rmtree(str_pic_path)
        os.makedirs(str_pic_path)
        # print('path of %s already exist and rebuild' % (savedpath))

    pics = os.listdir(pics_path)
    for pic in pics:
        pic_path = pics_path + '\\' + pic
        str_pic_name = str_pic_path + '\\' + pic.split('.')[0] + '.txt'

        # 转换
        img = Image.open(pic_path)
        img = img.resize((300, 200))  # 转换图像大小 可以调整字符串图像的长和宽

        if img.mode != "L":  # 如果不是灰度图像,转换为灰度图像
            im = img.convert("L")
        a = img.size[0]
        b = img.size[1]

        f = open(str_pic_name, 'w+')  # 目标文本文件

        for i in range(1, b, 2):
            line = ('')
            for j in range(a):
                line += table[int((float(im.getpixel((j, i))) / 256.0) * len(table))]
            line += ("\n")
            f.write(line)
        f.close()

    print('字符画完成')
    return str_pic_path

这里转换函数返回了保存的字符画集路径,为下一步骤做准备。

  • 第三步 按照顺序在终端打印 实现动画效果

# 第三步 把字符画按照顺序动态打印 实现动画效果
def play_str(play_dir):
    strs = os.listdir(play_dir)
    for str_txt in strs:
        real_dir = play_dir + '\\' + str_txt
        with open(real_dir, 'r') as f:
            ret = f.read()
        print(ret)
        time.sleep(0.05)
        subprocess.call('cls', shell=True)
  • 注意点

  1.  在终端打印时要把终端字体设置小一点,这样才能看到整体效果。
  2. 如果效果还是不太好,可以在第1步骤调整抽帧帧数,第2步骤中调整字符画大小,还有第三步骤调整打印速度。

 

完整代码

# -*- coding:utf8 -*-
import subprocess
import time
import cv2
import os
import shutil
from PIL import Image


# 第一步视频抽帧
def chouzhen(video_path):
    # 保存图片的路径
    savedpath = video_path.split('.')[0] + '/'
    isExists = os.path.exists(savedpath)
    if not isExists:
        os.makedirs(savedpath)
        # print('path of %s is build' % (savedpath))
    else:
        shutil.rmtree(savedpath)
        os.makedirs(savedpath)
        # print('path of %s already exist and rebuild' % (savedpath))

    # 视频帧率12
    fps = 12
    # 保存图片的帧率间隔
    count = 3

    # 开始读视频
    videoCapture = cv2.VideoCapture(video_path)
    i = 0
    j = 0
    while True:
        success, frame = videoCapture.read()
        i += 1
        if (i % count == 0):
            # 保存图片
            j += 1
            savedname = video_path.split('\\')[-1].split('.')[0] + '_' + '%04d' % j + '.jpg'
            cv2.imwrite(savedpath + savedname, frame)
            # print('image of %s is saved' % (savedname))

        if not success:
            print('抽帧完成')
            break


# 第二步 把抽帧得到的图片全部转化为字符画
def pic2str(video_path):
    ascil_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
    table = ('#8XOHLTI)i=+;:,. ')  # 对于灰度图像效果不错


    # 拿到保存图片的路径
    pics_path = video_path.split('.')[0]

    # 创建保存字符画的路径
    str_pic_path = video_path.split('.')[0] + '_str'
    isExists = os.path.exists(str_pic_path)
    if not isExists:
        os.makedirs(str_pic_path)
        # print('path of %s is build' % (savedpath))
    else:
        shutil.rmtree(str_pic_path)
        os.makedirs(str_pic_path)
        # print('path of %s already exist and rebuild' % (savedpath))

    pics = os.listdir(pics_path)
    for pic in pics:
        pic_path = pics_path + '\\' + pic
        str_pic_name = str_pic_path + '\\' + pic.split('.')[0] + '.txt'

        # 转换
        img = Image.open(pic_path)
        img = img.resize((300, 200))  # 转换图像大小 可以调整字符串图像的长和宽

        if img.mode != "L":  # 如果不是灰度图像,转换为灰度图像
            im = img.convert("L")
        a = img.size[0]
        b = img.size[1]

        f = open(str_pic_name, 'w+')  # 目标文本文件

        for i in range(1, b, 2):
            line = ('')
            for j in range(a):
                line += table[int((float(im.getpixel((j, i))) / 256.0) * len(table))]
            line += ("\n")
            f.write(line)
        f.close()

    print('字符画完成')
    return str_pic_path


# 第三步 把字符画按照顺序动态打印 实现动画效果
def play_str(play_dir):
    strs = os.listdir(play_dir)
    for str_txt in strs:
        real_dir = play_dir + '\\' + str_txt
        with open(real_dir, 'r') as f:
            ret = f.read()
        print(ret)
        time.sleep(0.05)
        subprocess.call('cls', shell=True)


# 程序入口
def run():
    # 开始
    # video_path = r'D:\pythoncode\app_shot_screens\video_chouzhen\dance.mp4' # 修改你要生成字符画的视频路径
    video_path = input('请输入要生成字符画的视频路径:') # 修改你要生成字符画的视频路径
    chouzhen(video_path)
    play_dir = pic2str(video_path)
    temp = input('转换完成 按任意键开始播放')
    play_str(play_dir)


if __name__ == '__main__':
    run()

 

你可能感兴趣的:(Python)