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

百家 作者:AI100 2019-04-11 09:14:05
点击上方↑↑↑蓝字关注我们~

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


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

编辑 | Jane


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


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


<iframe class="video_iframe rich_pages" data-vidtype="2" data-mpvid="wxv_755457897580167169" data-cover="http%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2F1skeHK2Gybx4iaa4GrrPMo0ZnZL3ZmbOdY4Dial0zIg1Sdxd96zGpq8oRV9tMBKWG6I2S3vYJRyEvNUTQVoia1sOA%2F0%3Fwx_fmt%3Djpeg" allowfullscreen="" frameborder="0" data-ratio="1.5769230769230769" data-w="574" scrolling="no" data-src="http://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&auto=0&vid=wxv_755457897580167169" width="352" height="198" data-vh="198" data-vw="352" style="display: none; width: 352px !important; height: 198px !important; overflow: hidden;"></iframe>


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


原理


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


在这里简单的说一下图片转字符画的原理:首先将图片转为灰度图,每个像素都只有亮度信息(用?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_image?ag)用于转换颜色空间,其中?ag就是转换类型。对于?BGR?Gray?的转换,我们使用的??ag?就是?cv2.COLORBGR2GRAY。对于?BGR?HSV?的转换我们用的??ag?就是?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('33[{}Ar'.format(rows?-1))
34
35#?光标下移?rows-1?行到最后一行,清空最后一行
36
37self.streamOut('33[{}B33[K'.format(rows?-1))
38
39#?清空最后一帧的所有行(从倒数第二行起)
40
41for?i?in?range(rows?-1):
42
43#?光标上移一行
44
45self.streamOut('33[1A')
46
47#?清空光标所在行
48
49self.streamOut('r33[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(微信同号)。


推荐阅读:




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

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接