让代码和迈克杰克逊一起跳舞

还记得读高中时,有一次和同学一次去网吧上网,他让我看一个视频,是 Michael Jackson 的前倾 45° 的动作,当时觉得舞蹈还可以这样跳,太炫酷了。那时在网吧看了 2 小时 MJ 的舞蹈。此后就迷上了 MJ,迷上了他的太空步,迷上了他的机械舞,迷上了他的超强节奏律动的歌曲,成为了小小的 MJFans。那时为了备战高考,我和这位同学一起在学校附近住了一间房间,那时镇上的房租也很便宜。学习累了,就一起在 MJ 的歌曲中练练太空步,乐此不疲。
大学期间,我还在宿舍没人时自己偷偷看视频练习 MJ 的舞蹈 dangerous,可惜自己基础太差,上不了台面,上台表演的梦想只好作罢。
如今都毕业几年了,手机也换得频繁,但手机里总会有 MJ 的歌,累了乏了就会听听,边听边跟着节奏一起打着节拍,听完之后感觉全身又充满了力量。看到有些视频软件上有人发布了 MJ 的视频,也总会忍不住点进去看看。
最近看到一个有意思的程序:ffmpeg。它是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。可以用来把视频转化为图片,在用 PIL 库把图片处理成编码,这样编码就可以和 MJ 视频一起律动起来了。
说干就干,首先打开之前收集的 MJ 的视频,把那些背景干扰比较少的镜头剪切下来处理。这个工作是个苦差,因为 MJ 的舞蹈视频基本都在演唱会上,背景比较多,效果不是太明显,再加上之前也很少用这些视频处理软件。弄了大半天总算拼了两段稍微好点的,配上了自己剪切的音乐。
这里不好上传本地视频,视频在公众号里可看,有兴趣的通过下方进入公众号去观看,这里放两张截图看看。
项目环境
语言: Python3
工具:Pycharm
工具准备
ffmpeg,刚才说的处理视频的程序,可去官网下载https://www.ffmpeg.org/download.html#build-windows,我的电脑是windows 64 位的,和我一样系统的话也可以公众号回复「ff」获取。
PIL 包:Python 的图形处理库。
numpy 包:Python 的一种开源的数值计算扩展,可用来存储和处理大型矩阵。
程序结构
我写了三个 py 文件,一个用来把视频转换为图片,一个用来把图片转为编码,最后一个来做最后的执行。
视频处理
下面的 ffmpeg 程序后面的几个参数我解释一下,-i 后面需要指定输入的文件名。-f 指定格式(音频或视频格式)。-vframes 设置转换多少桢(frame)的视频。-ss 从指定的时间(s)截图。
def getImage(videoPath, imagePath): img_count = 1 crop_time = 0.0 while crop_time <= 15.0: os.system('ffmpeg -i %s -f image2 -ss %s -vframes 1 %s.png'% (videoPath, str(crop_time), imagePath + str(img_count))) img_count += 1 print('Geting Image ' + str(img_count) + '.png' + ' from time ' + str(crop_time)) crop_time += 0.1 print('图片收集结束!!!') 复制代码
用这个函数获取视频的每帧图片,给出的视频存放路径和获取图片的路径调用此函数就可以获取视频每帧的图片,我设置了每 0.1 秒保存一张图片。
图片转换
用 convert('L') 把图片转换为为二值图像,非黑即白。但是它每个像素用 8 个bit 表示,0 表示黑,255 表示白。
def image2txt(inputFile, outputFile): im = Image.open(inputFile).convert('L') charWidth = 100 im = im.resize((charWidth, charWidth // 2)) target_width, target_height = im.size data = numpy.array(im)[:target_height, :target_width] f = open(outputFile, 'w',encoding='utf-8') for row in data: for pixel in row: if pixel > 127: f.write('1') else: f.write(' ') f.write('\n') f.close() 复制代码
执行这个函数不会有数据返回,用下一个 go.py 文件导入调用才行。
控制输出
调用上个函数 image2txt,图片转换为编码。
def getTxt(imagePath, txtPath): img_count = 1 while img_count <= len(os.listdir(imagePath)): imageFile = imagePath + str(img_count) + '.png' txtFile = txtPath + str(img_count) + '.txt' image2txt.image2txt(imageFile, txtFile) print('MJ舞蹈加载中: ' + str(img_count) + '%') img_count += 1 复制代码
通过 os.system('cls') 控制屏幕的及时清除,以便及时显示下一帧图片的编码。
def play(txtPath): txt_count = 1 while txt_count <= len(os.listdir(txtPath)): os.system('type ' + txtPath + str(txt_count) + '.txt') txt_count += 1 os.system('cls') 复制代码
给出编码文件路径和图片路径,执行函数。
txt_dir_path = r'D:\MJ\mjtxt' + '\\' img_dir_path = r'D:\MJ\mjimages' + '\\' getTxt(img_dir_path, txt_dir_path) play(txt_dir_path) 复制代码
收集完视频图片后在 cmd 控制台执行 go.py 文件,编码出现后点击视频播放就能达到刚才视频中的效果了。
你们可以用自己的视频去做,视频背景固定的话效果更好。
在公众号回复「MJ」获取源码。
写在最后
方法教给大家了,视频素材可以优化,大家可以自己收集好的视频素材,发到朋友圈,让代码骚动起来!觉得有意思的话希望大家能多给点支持,该关注关注,该点赞点赞,该转发转发,有什么问题欢迎在后台联系我,也可以在后台加入技术交流群,群里有大神,可以一起交流学习。
作者:brucepk
来源:掘金

工程师必备
- 项目客服
- 培训客服
- 平台客服
TOP
