作者:brucek 原文链接:https://mp.weixin.qq.com/s/lyiNDbDpw5mt24gVwO0YyA
最近看到一个有意思的程序: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 文件,编码出现后点击视频播放就能达到刚才视频中的效果了。
你们可以用自己的视频去做,视频背景固定的话效果更好。