上次写了个华强买瓜字符视频的帖子,下面有人问如何保存,所以这次就写一个能将字符画视频保存下来的帖子,然而时不待我,华强纪元已经结束,现在是穿山甲的时代了。
首先读取视频,并转为字符。视频是从B站下载的,地址《激战江南》穿山甲名场面。
由于B站直接下载的视频为flv格式,而imageio并不支持,尽管可以用opencv来读取,但相比之下,用ffmepg转个码也不复杂,这样可以最大限度地利用华强买瓜的代码。
另外,视频素材过长不适合代码演示,所以从第2:10进行截取15s。
在命令行中输www.cppcns.com入
>pip install ffmpeg >ffmpeg -i soup.flv -ss 00:02:10 -t 15 seg.mp4 -y
很快就得到了seg.mp4,接下来就是读取视频并转为字符,有关这部分代码的解析,可出门左转华强买瓜。
import imageio import numpy as np import matplotlib.pyplot as plt video = imageio.get_reader('seg.mp4') imgs = [np.mean(im,2) for im in video] plt.imshow(imgs[30]) plt.show()
这个视频对于字符画而言太大了,所以转字符画之前需对其压缩。这里采取最简单的方法——即对相邻的像素取平均值。
#将图像宽度缩小至width from itertools import product #用于循环嵌套 http://www.cppcns.comdef resizeImg(img,w,h=None): m,n = img.shape if n<w: return img if not h: h = int(m*w/n) im = np.zeros([h,w]) rw,rh = n/w,m/h #缩放比例 dw,dh = int(rw),int(rh) #取均值的步长 for i,j in product(range(h),range(w)): I,J = int(i*rh),int(j*rw) im[i,j] = np.mean(img[I:I+dh,J:J+dw]) return im # 测试一下 im = resizeImg(imgs[30],160) plt.imshow(im) plt.show()
接下来生成字符画,在此使用matplotlib中的text来进行绘制,出于观感考虑,取消了坐标轴。考虑到字符画需要宽度一致,故启用本地字体。
关于绘图字体,可参考python画图时调用本地字体
pixels = "B8&WMZO0QJX@%&jfoavunxr#t/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ^`'. " #用于映射的字符 def im2txt(img): im = np.floor(img/255*len(pixels)).astype(int) txts = "" for line in im: txts += "".join([pixels[i] for i in line]) txts += '\r\n' #像素换行时文本也要换行 r编程客栈eturn txts #测试 txt = im2txt(im) plt.figure(figsize=(8,4.5)) plt.rcParams['font.sans-serif'] = 'SIMSUN' #SIMSUN为宋体 plt.axis([0,10,0,10]) _ = plt.text(5, 5, txt, fontsize=6, linespacing=0.6,ha='center', va='center',wrap=True) plt.gca().set_axis_off() piFjsTChlt.show()
结果如下
接下来就是动起来,对于老粉来说这个显然很简单,属于PythonArt这个系列的传统艺能了。。。
from matplotlib import animation fig = plt.figure(figsize=(8,4.5)) plt.rcParams['font.sans-serif'] = 'SIMSUN' ax = fig.add_subplot(xlim=(0,10),ylim=(0,10)) ax.set_axis_off() text = ax.text(5, 5, txt, fontsize=6, linespacing=0.6, ha='center', va='center',wrap=True) def animate(im编程客栈): text.set_text(im2txt(im)) return [text] imgs = [resizeImg(im,160) for im in imgs] ani = animation.FuncAnimation(fig, animate, imgs[:200], interval=10, blit=True) plt.show()
最终得到
到此这篇关于Python实现视频转换为字符画详解的文章就介绍到这了,更多相关Python视频转字符画内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
精彩评论