基于Python实现视频转字符画动漫小工具
程序员文章站
2022-03-08 19:12:39
目录导语正文一、准备中二、原理简介三、代码演示四、效果展示导语哈喽!boys and girls 我是每天疯狂赶代码的木木子~今天带大家来点儿好玩儿的东西,我想你们肯定是喜欢的!上面这个大家都认识...
导语
哈喽!boys and girls 我是每天疯狂赶代码的木木子~
今天带大家来点儿好玩儿的东西,我想你们肯定是喜欢的!
上面这个大家都认识吧
对,就是字符动画啦,之前也是不是再那个旮旯里面看见过,但是还没上手自己试的。
小编给大家先试试效果了,效果也是真不错,趣味性蛮强滴 推荐指数5颗星,大家都开始动手
燥起来吧~
那么如何将视频动画转成字符画呢?今天就来教大家怎么转换,非常简单,今天教大家制作的
这款工具就能一键转换!
正文
一、准备中
1)素材的话可以自己找一小段视频的哈。
2)环境安装
本文用到的环境如下:python3、pycharm、numpy、cv2以及部分自带模块。
模块安装:
pip install -i https://pypi.douban.com/simple/ +模块名
二、原理简介
1)视频转为一帧帧的图片这个利用opencv就可以实现了。
2)**将每帧图片转为字符画,**原理是根据图片的像素值确定每个像素点用什么字符。
3)按顺序播放字符画即可。
三、代码演示
# 视频转字符动画 import os import cv2 import sys import time import ctypes import subprocess import numpy as np # 暗蓝色 foreground_darkblue = 0x01 # 暗绿色 foreground_darkgreen = 0x02 # 暗天蓝色 foreground_darkskyblue = 0x03 # 暗红色 foreground_darkred = 0x04 # 暗粉红色 foreground_darkpink = 0x05 # 暗黄色 foreground_darkyellow = 0x06 # 暗白色 foreground_darkwhite = 0x07 # 暗灰色 foreground_darkgray = 0x08 # 蓝色 foreground_blue = 0x09 # 绿色 foreground_green = 0x0a # 天蓝色 foreground_skyblue = 0x0b # 红色 foreground_red = 0x0c # 粉红色 foreground_pink = 0x0d # 黄色 foreground_yellow = 0x0e # 白色 foreground_white = 0x0f # 上面颜色对应的rgb值 cmd_colors = { 'foreground_darkblue': [foreground_darkblue, (0, 0, 139)], 'foreground_darkgreen': [foreground_darkgreen, (0, 100, 0)], 'foreground_darkskyblue': [foreground_darkskyblue, (2, 142, 185)], 'foreground_darkred': [foreground_darkred, (139, 0, 0)], 'foreground_darkpink': [foreground_darkpink, (231, 84, 128)], 'foreground_darkyellow': [foreground_darkyellow, (204, 204, 0)], 'foreground_darkwhite': [foreground_darkwhite, (255, 250, 250)], 'foreground_darkgray': [foreground_darkgray, (169, 169, 169)], 'foreground_blue': [foreground_blue, (0, 0, 255)], 'foreground_green': [foreground_green, (0, 128, 0)], 'foreground_skyblue': [foreground_skyblue, (135, 206, 235)], 'foreground_red': [foreground_red, (255, 0, 0)], 'foreground_pink': [foreground_pink, (255, 192, 203)], 'foreground_yellow': [foreground_yellow, (255, 255, 0)], 'foreground_white': [foreground_white, (255, 255, 255)] } chars = " .,-'`:!1+*abcdefghijklmnopqrstuvwxyz<>()\/{}[]?234567890abcdefghijklmnopqrstuvwxyz%&@#$" ''' function: 视频转图片 input: -videopath: 视频路径 -size: 指定图片大小 -interval: 视频每interval帧取一帧 return: -img_list: 图像列表 ''' def video2imgs(videopath, size, interval=1): img_list = list() capture = cv2.videocapture(videopath) i = -1 while capture.isopened(): i += 1 ret, frame = capture.read() if ret: if i % interval == 0: # frame = cv2.cvtcolor(frame, cv2.color_bgr2gray) img = cv2.resize(frame, size, interpolation=cv2.inter_area) img_list.append(img) else: break capture.release() return img_list ''' # 根据距离将图片的rgb值转为windows-cmd窗口支持的颜色 def rgb2cmdcolor(color): cmd_color = none min_distance = 1e6 for key, value in cmd_colors.items(): distance = np.square(np.array(color) - np.array(value[1])).sum() if distance < min_distance: min_distance = distance cmd_color = value[0] return cmd_color ''' ''' function: 图像转字符画 input: -img(np.array): 图像 return: -img_chars: 像素点对应的字符集合 ''' def img2chars(img): img_chars = [] height, width, channel = img.shape for row in range(height): line = "" for col in range(width): percent = int(np.array(img[row][col]).sum() / 3) / 255 char_idx = int(percent * (len(chars) - 1)) line += chars[char_idx] + ' ' img_chars.append(line) return img_chars ''' function: 视频转字符画s input: -imgs: 视频里捕获的所有图片 return: -video_chars: img_chars的集合 ''' def imgs2chars(imgs): video_chars = [] for img in imgs: video_chars.append(img2chars(img)) return video_chars ''' function: 播放字符画s input: -video_chars: imgs2chars中获取的video_chars -iscmd(bool): 是否在windows的cmd窗口播放 -color: 颜色选择, cmd中有效 ''' def play(video_chars, color=none, iscmd=true): if color and iscmd: std_output_handle = -11 std_out_handle = ctypes.windll.kernel32.getstdhandle(std_output_handle) color_choice = none if color.isdigit(): color_choice = list(cmd_colors.values())[int(color)][0] else: color_choice = cmd_colors.get(color)[0] if color_choice is not none: _ = ctypes.windll.kernel32.setconsoletextattribute(std_out_handle, color_choice) width, height = len(video_chars[0][0]), len(video_chars[0]) for img_chars in video_chars: for row in range(height): print(img_chars[row]) time.sleep(1/24) if iscmd: os.system('cls') else: subprocess.call("clear") # 主函数 def main(videopath, color=none, iscmd=true): imgs = video2imgs(videopath=videopath, size=(64, 48), interval=1) video_chars = imgs2chars(imgs) input("[info]: complete pre-processing! enter <enter> button to start to play...") if iscmd: os.system('cls') else: subprocess.call("clear") play(video_chars, color=color, iscmd=true) if __name__ == '__main__': import argparse parser = argparse.argumentparser() parser.add_argument('-f', '--file', help='video file.') parser.add_argument('-c', '--color', help='color for playing.') args = parser.parse_args() main(args.file, color=args.color)
四、效果展示
1)截图效果展示
第一组随机截图:
第二组随机截图:
第三组随机截图:
以上就是基于python实现视频转字符画动漫小工具的详细内容,更多关于python视频转字符画的资料请关注其它相关文章!
上一篇: 人生这样的时刻属实不多