用Python让蔡徐坤在我的命令行里打篮球!|附完整代码

news/2024/7/5 6:07:04
640?wx_fmt=gif点击上方↑↑↑蓝字关注我们~

640?wx_fmt=jpeg

2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑


来源 | 01二进制(ID:gh_d1999add1857)

编辑 | Jane


【导语】作者自称是一个经常逛 B 站的肥宅。最近 B 站上流行的视频素材除了“换脸”,其次就要属“蔡xx打球”视频了。有模仿的、对比的、手绘的... ...更过分的是,竟然有人在命令行输出了他的打球视频。不过,视频中的动画好像是用某个软件生成的 txt 文件,作者就在想既然都可以用 txt 输出了,能不能用 python 在命令行中显示呢?


说到这作者便开始搜索资料,做后制作了下面一段视频“



代码是自己在网上查询资料后自己修改的,本着学习和分享的精神,今天就来分享下上面这段视频的制作过程。


原理


既然要开始做东西,首要的问题就是想好要怎么做,大家都知道视频是由一系列图片一帧一帧组成的,因此视频转字符动画最基本的便是图片转字符画。


在这里简单的说一下图片转字符画的原理:首先将图片转为灰度图,每个像素都只有亮度信息(用 0~255 表示)。然后我们构建一个有限字符集合,其中的每一个字符都与一段亮度范围对应,我们便可以根据此对应关系以及像素的亮度信息把每一个像素用对应的字符表示,这样字符画就形成了。

Tips:如果对"灰度图像"这个概念不太理解的可以查阅百度百科

计算一张图片的灰度图像的方法如下(来自百度百科):


640?wx_fmt=jpeg


所以我们要做的就只是让字符画在命令行里面动起来就可以了。

Tips:图片转字符画可以参考:https://www.shiyanlou.com/courses/370

准备


环境和工具:vscode、Mac OS、python 3.7

这次实验使用到的核心的库是opencv-python


Tips:这里分享一个我觉得还不错的opencv-python的中文文档:https://www.kancloud.cn/aollo/aolloopencv/269602

实验


实验开始前我们需要安装 opencv-python 的包:



1pip install opencv



读取视频:



1def genCharVideo(self, filepath):
2
3self.charVideo =[]
4
5# 用opencv读取视频
6
7cap = cv2.VideoCapture(filepath)
8
9self.timeInterval = round(1/ cap.get(5),3)
10
11nf = int(cap.get(7))
12
13print('Generate char video, please wait...')
14
15for i in pyprind.prog_bar(range(nf)):
16
17# 转换颜色空间,第二个参数是转换类型,cv2.COLOR_BGR2GRAY表示从BGR↔Gray
18
19rawFrame = cv2.cvtColor(cap.read()[1], cv2.COLOR_BGR2GRAY)
20
21frame = self.convert(rawFrame, os.get_terminal_size(), fill=True)
22
23self.charVideo.append(frame)
24
25cap.release()



这里的VideoCapture是用来读取视频的, cv2.cvtColor(input_imageflag)用于转换颜色空间,其中flag就是转换类型。对于 BGR↔Gray 的转换,我们使用的 flag 就是 cv2.COLORBGR2GRAY。对于 BGR↔HSV 的转换我们用的 flag 就是 cv2.COLORBGR2HSV。


将帧转换成字符画



1ascii_frame
2
3ascii_char ="$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
4
5
6
7# 像素映射到字符
8
9def pixelToChar(self, luminance):
10
11return self.ascii_char[int(luminance /256* len(self.ascii_char))]
12
13
14
15# 将普通帧转为 ASCII 字符帧
16
17def convert(self, img, limitSize=-1, fill=False, wrap=False):
18
19if limitSize !=-1and(img.shape[0]> limitSize[1]or img.shape[1]> limitSize[0]):
20
21img = cv2.resize(img, limitSize, interpolation=cv2.INTER_AREA)
22
23ascii_frame =''
24
25blank =''
26
27if fill:
28
29blank +=' '*(limitSize[0]- img.shape[1])
30
31if wrap:
32
33blank +='\n'
34
35for i in range(img.shape[0]):
36
37for j in range(img.shape[1]):
38
39ascii_frame += self.pixelToChar(img[i, j])
40
41ascii_frame += blank
42
43return ascii_frame



这段代码其实就是将已经转变的灰度图的像素值映射到 ascii_char上,然后输出到控制台。


控制输出


1# 创建线程
2
3getchar = threading.Thread(target=getChar)
4
5# 设置为守护线程
6
7getchar.daemon =True
8
9# 启动守护线程
10
11getchar.start()
12
13# 输出的字符画行数
14
15rows = len(self.charVideo[0])// os.get_terminal_size()[0]
16
17for frame in self.charVideo:
18
19# 接收到输入则退出循环
20
21if breakflag:
22
23break
24
25self.streamOut(frame)
26
27self.streamFlush()
28
29time.sleep(self.timeInterval)
30
31# 共 rows 行,光标上移 rows-1 行回到开始处
32
33self.streamOut('\033[{}A\r'.format(rows -1))
34
35# 光标下移 rows-1 行到最后一行,清空最后一行
36
37self.streamOut('\033[{}B\033[K'.format(rows -1))
38
39# 清空最后一帧的所有行(从倒数第二行起)
40
41for i in range(rows -1):
42
43# 光标上移一行
44
45self.streamOut('\033[1A')
46
47# 清空光标所在行
48
49self.streamOut('\r\033[K')
50
51if breakflag:
52
53self.streamOut('User interrupt!\n')
54
55else:
56
57self.streamOut('Finished!\n')


执行


最后在main函数中设置下要读取的文件名,再play一下就可以了


1if
2__name__ =='__main__':
3
4v2char = V2Char('vedio.mp4')
5
6v2char.play()



完整代码链接:

https://pan.baidu.com/s/1ZTc2a7DU-NIneI-CCbPu8Q 

提取码: jc3n 

作者简介:雇个城管打天下,理工男一枚。南京大学软件工程系硕士,一个还在做着拥有十万读者梦的互联网新人,或许一篇文章无法获得你的关注,但突然梦想觉醒的我还在努力着!


(本文为AI科技大本营转载文章,转载请微信联系原作者)



倒计时两天


「2019 Python开发者日」演讲议题全揭晓!这一次我们依然“只讲技术,拒绝空谈”10余位一线Python技术专家共同打造一场硬核技术大会。更有深度培训实操环节,为开发者们带来更多深度实战机会。目前大会倒计时 2 天,更多详细信息请咨询13581782348(微信同号)。


640?wx_fmt=jpeg

推荐阅读:


  • 39个国外SCI抢发6万篇中国英文论文?然而,真正的问题是……

  • 专访博世王红星:大数据和AI将是中国制造业升级新动力

  • 抵制996!Python之父发声背后,这个社区一呼百应!

  • 什么是网络爬虫?有什么用?怎么爬?终于有人讲明白了

  • 京东或将裁员 12000 人!雷军年薪百亿;马云:阿里没人敢跟我打赌 | 极客头条

  • 偷电、挖矿、赚快钱,这些大学生到底怎么了?

  • 终于有人把5G和边缘计算的关系说清楚了 | 技术头条

  • 频繁跳槽涨工资?会影响征信的!| 畅言

  • 刺激!我31岁敲代码10年,明天退休!


640?wx_fmt=png


点击“阅读原文”,了解「2019 Python开发者日」


http://lihuaxi.xjx100.cn/news/284300.html

相关文章

MVC框架模式技术实例(用到隐藏帧、json、仿Ajax、Dom4j、jstl、el等)

前言&#xff1a; 刚刚学完了MVC&#xff0c;根据自己的感悟和理解写了一个小项目。 完全按照MVC模式&#xff0c;后面有一个MVC的理解示意图。 用MVC模式重新完成了联系人的管理系统&#xff1a; 用户需求&#xff1a; 多用户系统&#xff0c;提供用户注册、登录功能&#xf…

介绍java -cp java -jar的区别

java -cp 和 -classpath 一样&#xff0c;是指定类运行所依赖其他类的路径&#xff0c;通常是类库&#xff0c;jar包之类&#xff0c;需要全路径到jar包&#xff0c;window上分号“;” java -cp & java jar格式 java -cp和-classpath一样&#xff0c;是指定类运行所依赖其…

关于Linux下编译C文件出现storge size of ‘act‘ isn‘t know和never include <bits/sigaction.h> directory:usr<signal

1.出现以下问题&#xff1a;这个是在使用struct sigaction act;中出现了问题 提示&#xff1a;可以看到提示我们说“不知道这个act的存储大小” &#xff0c;那就说明找不到&#xff0c;很有可能是缺少什么头文件&#xff1a; 网上提示我们加入头文件&#xff1a;#include<b…

【C语言刷题】交换两个变量(包含不创建临时变量)的解法

目录一.常规方法&#xff08;引入空瓶变量&#xff09;二.题目要求&#xff0c;不允许创建临时变量2.1 通过两数加法实现交换2.2 按位异或操作符实现交换题目&#xff1a;写代码实现两个变量的交换。&#xff08;不允许创建临时变量&#xff09;一.常规方法&#xff08;引入空瓶…

抵制996!Python之父发声背后,这个社区一呼百应!

「2019 Python开发者日」全日程揭晓&#xff0c;请扫码咨询 ↑↑↑这一次&#xff0c;程序员们也终于见证了一次 Python 社区的强大能量&#xff01;3 月底&#xff0c;996.ICU 话题诞生后&#xff0c;目前已在 GitHub Trending 上总计获得了近 23 万个 Star&#xff0c;一度冲…

图像去噪的深度学习最新综述论文,36页pdf,Deep Learning on Image Denoising

图像去噪是学术工业关注的问题。最近广东深圳哈工大分院的研究人员撰写了最新图像去噪深度学习的综述论文&#xff0c;非常值得学习&#xff01;关注文章公众号对话框回复“paper29”获取本篇论文地址&#xff1a;https://arxiv.org/abs/1912.13171简介&#xff1a;深度学习技术…

关于组培的一些想法(求知解惑),多肉科普

本文抛砖引玉&#xff0c;根据自己这段时间的看帖学习&#xff0c;提出自己的一些想法&#xff0c;希望各位看官特别是专家的指正 何为组培 所谓组培就是无性繁殖&#xff0c;商家组培的是一种&#xff0c;叶插是其实也是一种&#xff0c;有人说是介于种子繁殖和克隆之间的一种…

Linux 中 rsync 备份数据使用实例

rsync工具用于将文件和目录从一个位置同步到另一个位置。同步的位置可以在本地服务器或远程服务器上。接下来教大家在Linux 中rsync备份数据使用实例 在Centos中使用下面命令安装rsync&#xff1a; [rootlocalhost ~]# yum -y install rsync 实例一&#xff1a;本机中的两个目…