- Demo:bilibili
- Using:Python 3.5,ffmpeg-bin
- Dependence:PIL,string,numpy,math
务必注意这只是Prototype,性能可以说是完全没有的
首先截取画面,命令行如下
ffmpeg -ss TIME -t DURING -i INPUT -frames:v TOTAL OUTPUT
- TIME:开始截取的时间
- DURING:截取时长
- INPUT:视频文件名
- TOTAL:截取帧数
- OUTPUT:输出的图片名(例如pic%d.png,将生成pic1.png,pic2.png,…)
接着Python
from PIL import Image,ImageDraw,ImageFont
import string
import numpy
import math
FontSize=24
font = ImageFont.truetype('consola.ttf',FontSize)
FontPxSize=font.getsize('A')
LetterLuma={}
LetterUsed="qwertyuiopasdfghjklzxcvbnm[];',.{}:\"<>?~!@#$%^&*()_+-=123456789/"
#允许使用的字符
for letter in LetterUsed:
imgl=Image.new('RGB',FontPxSize,(255,255,255))
drawl=ImageDraw.Draw(imgl)
drawl.text((0,0),letter,(0,0,0),font=font)
dat=list(imgl.getdata())
ave=numpy.average(dat)
LetterLuma[letter]=ave
LetterLuma[' ']=255
LowID=1 #图片开始的序号
HighID=2 #图片结束的序号+1
IDafx='k' #图片编号前缀
fload='' #图片位置
QuickGuess={}
for id in range(LowID,HighID):
filename=fload+IDafx+str(id)+'.png' #假设图片为png格式
img=Image.open(filename)
img.load()
img=img.convert("L")
imgsize=img.size
maxrow=math.floor(imgsize[1]/FontPxSize[1])
maxcol=math.floor(imgsize[0]/FontPxSize[0])
linesize=imgsize[1]
pxwidth=FontPxSize[0]
pxheight=FontPxSize[1]
outputimg=Image.new('RGB',(maxcol*FontPxSize[0],maxrow*FontPxSize[1]),(255,255,255))
outputdraw=ImageDraw.Draw(outputimg)
for h in range(0,maxrow):
RanderText=''
TextCache=[]
for w in range(0,maxcol):
'''
开始计算平均灰度
'''
l=0.0
l=numpy.average(list((img.getpixel((x,y)) for x in range(w*pxwidth,(w+1)*pxwidth) for y in range(h*pxheight,(h+1)*pxheight))))
'''l/=FontPxSize[0]*FontPxSize[1]'''
bestguess=' '
if (QuickGuess.get(int(l))==None):
for key in LetterLuma:
if (abs(LetterLuma[bestguess]-l)>abs(LetterLuma[key]-l)):
bestguess=key
QuickGuess[int(l)]=bestguess
else:
bestguess=QuickGuess[int(l)]
TextCache.append(bestguess)
RanderText=RanderText.join(TextCache)
outputdraw.text((0,h*pxheight), RanderText,(0,0,0),font=font)
outputimg.save(fload+IDafx+'MOD'+str(id)+'.png')
img.close()
最后再用ffmpeg合成,命令行如下
ffmpeg -framerate FRAMERATE -i PICINPUT -codec copy FILMOUTPUT
- FRAMERATE:帧率
- PICINPUT:图片
- copy:指定的视频压缩格式为仅复制(可换成h264)
- FILMOUTPUT:输出视频
为了快速开发所以没有用getdata方法把数据导出list再计算平均灰度考虑对齐问题好烦啊这是性能瓶颈之一,因为getpixel方法比average方法的CPU耗时多
另外一个可能瓶颈在于硬盘IO,数据从硬盘流到内存(ffmpeg解码)再流回硬盘(保存为png)再流到内存(解码png)再流到硬盘(保存为png)再流到内存(ffmpeg编码)再流到硬盘(保存为视频),鉴于不知道有没有Python上包装ffmpeg的库,可以用C写两个函数,然后黏到Python上。
Demo在8核3.2GHz的处理器上,ffmpeg截图约50 fps,Python处理(多进程)约1 fps,ffmpeg合成约300 fps
发表回复
要发表评论,您必须先登录。