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

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

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

原理

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

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

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

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

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

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

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

今日学习推荐

【机器学习集训营第八期】

火热报名中

2019年5月6日开课

前140人特惠价:15199 

报名加送18VIP[包2018全年在线课程和全年GPU]

且两人及两人以上组团还能各减500元

有意的亲们抓紧时间喽

咨询/报名/组团可添加微信客服

julyedukefu_02

扫描下方二维码

免费试听

长按识别二维码

●知道什么是B树,那你知道什么是R树吗?

●什么?互联网人恋爱调查报告,程序员竟成最大赢家?

●金融风控面试十二问

●一次面试让你知道数据结构与算法对前端的重要性

●人工智能人才争抢白热化?学好数学才能C位出道!

●哪些机器学习算法不需要做归一化处理?

●一文详解:什么是B树?

●机器学习中的数学基础(微积分和概率统计)

●34个最优秀好用的Python开源框架

●【实战分享】电影推荐系统项目实战应用

●Python打牢基础,从19个语法开始!

扫描下方二维码  关注:七月在线实验室 

后台回复:100   免费领取【机器学习面试100题】

后台回复:干货 免费领取全体系人工智能学习资料

后台回复: 领资料 【NLP工程师必备干货资料】

▼更多精彩推荐,请关注我们▼戳“阅读原文”我们一起进步在看点一下

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

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

    点击上方↑↑↑蓝字关注我们~ 「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑ 来源 | 01二进制(ID:gh_d1999add1857) 编辑 | Jane [导语]作者自称是一个 ...

  2. 用Python让蔡徐坤在我的命令行里打篮球~技术流追星!

    「2019 Python开发者日」倒计时三天,请扫码咨询 ↑↑↑ 作者 | 雇个城管打天下,理工男一枚.南京大学软件工程系硕士,一个还在做着拥有十万读者梦的互联网新人,或许一篇文章无法获得你的关注,但 ...

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

    点击上方↑↑↑蓝字关注我们~ 「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑ 来源 | 01二进制(ID:gh_d1999add1857) 编辑 | Jane [导语]作者自称是一个 ...

  4. Python 让蔡徐坤在我的命令行里打篮球!| 技术头条

    作者 | 雇个城管打天下 责编 | 伍杏玲 本文经授权转载自01二进制(ID:gh_d1999add1857) [CSDN 编者按]作者自称是一个经常逛 B 站的肥宅.最近 B 站上流行的视频素材除了 ...

  5. Python 让蔡徐坤在我的命令行里打篮球!

    既然要开始做东西,首要的问题就是想好要怎么做,大家都知道视频是由一系列图片一帧一帧组成的,因此视频转字符动画最基本的便是图片转字符画. 在这里简单的说一下图片转字符画的原理:首先将图片转为灰度图,每个 ...

  6. python运行cmd命令和opencv搭建_Python让蔡徐坤在我的命令行里打篮球!

    原标题:Python让蔡徐坤在我的命令行里打篮球! 作者自称是一个经常逛 B 站的肥宅.最近 B 站上流行的视频素材除了"换脸",其次就要属"蔡xx打球"视频了 ...

  7. python 把numpy.ndarray转为图像_Python 让蔡徐坤在我的命令行里打篮球?打得还不错...

    这是恋习Python推荐的第83篇好文 作者:顾个城管打天下 作者自称是一个经常逛 B 站的肥宅.最近 B 站上流行的视频素材除了"换脸",其次就要属"蔡xx打球&quo ...

  8. 用Go让蔡徐坤在我的命令行里打篮球!附示例gif和完整代码

    github地址

  9. python篮球-用Python把蔡徐坤打篮球视频转换成字符动画!

    原标题:用Python把蔡徐坤打篮球视频转换成字符动画! 说到现在网络最火的梗,非"蔡徐坤打篮球"莫属.最近,蔡徐坤当仁不让地成为了娱乐圈被黑的最惨的明星. 自从2019年1月份, ...

最新文章

  1. 编程控制Word文档中Table的赋值
  2. “AV终结者/8749”病毒清理办法
  3. python:列表增加元素,删除元素,切片等
  4. Android 开发笔记 Google地图定位与路线显示
  5. python staticmothed classmethod
  6. linux下源码安装cmake
  7. Spark配置参数详解
  8. 利用JS实现点击上一周或下一周却换
  9. Linux笔记-Centos7编译安装GmSSL
  10. 去中心化交易所协议0x protocol A轮融资获IOSG Ventures 支持
  11. PMP/PRINCE2/IPMP/软考,主流项目管理认证对比
  12. 32767+1=-32768 补码
  13. 应用商店提示0x80070005错误
  14. 滴滴出行DIDI美国IPO上市路演PPT:Roadshow Presentation
  15. linux 机器无法访问网络
  16. 联想笔记本拯救者Y7000盒盖不休眠问题,Win10
  17. 微信H5页面禁止分享朋友和复制链接
  18. [计算机数值分析]牛顿下山法求方程的根
  19. 用户账户计算机管理员密码,电脑管理员密码是什么
  20. python中的内置高阶函数

热门文章

  1. K8S有状态静态Pod经典示例
  2. 2021年安全员-A证(广西省-2021版)考试及安全员-A证(广西省-2021版)考试试卷
  3. 【JavaScript-9】Javascript中的布尔值和等式
  4. android指定sim卡拨号,android – 在双SIM卡设备中使用指定的SIM拨打电话
  5. hive olap 数据仓库_数据仓库:OLTP与OLAP查询
  6. 会议室应用中的“三块屏”
  7. 2013 网易校园招聘试题考点
  8. 不管是否情愿,5G要来了,运营商该做的事一样也不能少
  9. 关于浏览器自动安装Screenshot Pro拓展的问题
  10. MySQL中的子查询(第八章)