Python实现视频转字符画 |
|
DDUU
L0
• 2018-11-09 • 回复 10 • 只看楼主
• 举报
|
先看看效果(别人的):
视频:BadApple(百度云链接)
接下来上代码吧:
#-*- coding:utf-8 -*-
import numpy as np#这个模块和下面这个不是自带的,需要用pip安装
import cv2#
import time
import subprocess#这个是Windows系统需要的
#import curses这个是linux系统的
# 用于生成字符画的像素,越往后视觉上越明显。。这是我自己按感觉排的,你可以随意调整。
pixels = " .,-'`:!1+*abcdefghijklmnopqrstuvwxyz<>()\/{}[]?234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ%&@#$"
def video2imgs(video_name, size):
"""
:param video_name: 字符串, 视频文件的路径
:param size: 二元组,(宽, 高),用于指定生成的字符画的尺寸
:return: 一个 img 对象的列表,img对象实际上就是 numpy.ndarray 数组
"""
print("正在把视频转化为图片数组......")
img_list = []
# 从指定文件创建一个VideoCapture对象
cap = cv2.VideoCapture(video_name)
# 如果cap对象已经初始化完成了,就返回true,换句话说这是一个 while true 循环
while cap.isOpened():
# cap.read() 返回值介绍:
# ret 表示是否读取到图像
# frame 为图像矩阵,类型为 numpy.ndarry.
ret, frame = cap.read()
if ret:
# 转换成灰度图。
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# resize 图片,保证图片转换成字符画后,能完整地在命令行中显示。
img = cv2.resize(gray, size, interpolation=cv2.INTER_AREA)
# 分帧保存转换结果
img_list.append(img)
else:
break
# 结束时要释放空间
cap.release()
#返回了一个数组的列表
return img_list
def img2chars(img):
res = []
"""
:param img: numpy.ndarray, 图像矩阵
:return: 字符串的列表:图像对应的字符画,其每一行对应图像的一行像素
"""
# 要注意这里的顺序和 之前的 size 刚好相反
height, width = img.shape
for row in range(height):
line = ""
for col in range(width):
# 灰度是用8位表示的,最大值为255。
# 这里将灰度转换到0-1之间
percent = img[row][col] / 255
# 将灰度值进一步转换到 0 到 (len(pixels) - 1) 之间,这样就和 pixels 里的字符对应起来了
index = int(percent * (len(pixels) - 1))
# 添加字符像素(最后面加一个空格,是因为命令行有行距却没几乎有字符间距,用空格当间距)
line += pixels[index] + " "
res.append(line)
return res
def imgs2chars(imgs):
print("正在把数组转化为字符画......")
video_chars = []
for img in imgs:
video_chars.append(img2chars(img))
return video_chars
def play_video(video_chars):
"""
播放字符视频Windows版
:param video_chars: 字符画的列表,每个元素为一帧
:return: None
"""
# 获取字符画的尺寸
width, height = len(video_chars[0][0]), len(video_chars[0])
for pic_i in range(len(video_chars)):
# 显示 pic_i,即第i帧字符画
for line_i in range(height):
# 将pic_i的第i行写入第i列。
print(video_chars[pic_i][line_i])
time.sleep(1 / 24) # 粗略地控制播放速度。
subprocess.call("cls",shell=True) # 调用shell命令清屏
##def play_video(video_chars):
## """
## 播放字符视频Linux版
## :param video_chars: 字符画的列表,每个元素为一帧
## :return: None
## """
## # 获取字符画的尺寸
## width, height = len(video_chars[0][0]), len(video_chars[0])
##
## # 初始化curses,这个是必须的,直接抄就行
## stdscr = curses.initscr()
## curses.start_color()
## try:
## # 调整窗口大小,宽度最好略大于字符画宽度。另外注意curses的height和width的顺序
## stdscr.resize(height, width * 2)
##
## for pic_i in range(len(video_chars)):
## # 显示 pic_i,即第i帧字符画
## for line_i in range(height):
## # 将pic_i的第i行写入第i列。(line_i, 0)表示从第i行的开头开始写入。最后一个参数设置字符为白色
## stdscr.addstr(line_i, 0, video_chars[pic_i][line_i], curses.COLOR_WHITE)
## stdscr.refresh() # 写入后需要refresh才会立即更新界面
##
## time.sleep(1 / 24) # 粗略地控制播放速度。更精确的方式是使用游戏编程里,精灵的概念
## finally:
## # curses 使用前要初始化,用完后无论有没有异常,都要关闭
## curses.endwin()
## return
if __name__ == "__main__":
imgs = video2imgs("BadApple.mp4", (64, 48))#这里可以自己选择视频,和所输出的宽高
video_chars = imgs2chars(imgs)
input("`转换完成!按enter键开始播放")
play_video(video_chars)
保存为video2word.py
代码完成啦,接下来就是播放了,win10在代码文件的目录下shift+右键,打开powershell,最大化,键入python video2word.py,等待一段时间,就可以看到啦(会闪闪的)。最佳选择还是Linux终端(不咋会闪)。
这是自己弄得:
转载自:https://www.cnblogs.com/kirito-c/p/5971988.html
↓↓最后,留几个赞赞吧~?↓↓