背景:
这篇博客是我看到一个视频,使用python实现的一个趣味代码,然后就自己尝试实现了一下,以此记录一下整个过程。
内容:
主要实现的内容就是使用mmfpeg这个工具,实现对视频的读取,然后从视频中按照一定的帧率提取出来照片,再将这些照片转化为灰度图像,设定合适的阈值,找到符合阈值的灰度值的位置。
首先给大家看一下结果,然后再一步一步说明怎么实现的:
1. 这是在网上找的一个GIF图,然后转成MP4视频
2. 运行结果如下(博客好像不能插入视频,我就截了几张图):
前期准备:
首先要下载ffmpeg,这里只说Windows下的方式(linux不难),首先去官网,下载Windows版本的安装包
下载完成后,解压,放到你喜欢的位置,然后找到目录下的bin文件夹,将该目录放到你的环境变量中(如何配置环境变量这里不细说,百度之。)
之后就是测试一下有没有配置成功,打开你的
cmd
,输入ffmpeg -version
,输出以下东西,就是成功了
目录结构
我们的思路是视频——>图片——>txt文件,再“播放”这些txt文件。所以在你的工作目录下要放2个文件夹
image
和txt
,分别存放图像和txt文件,看一下我的目录test.py
文件就是我们要写的python文件了。
代码解释:
我们有三个函数,分别实现视频转图片,图片转txt,和main函数。
首先第一个函数get_image(video_path, image_path)
,两个参数就是你的视频路径和存放图片的路径。变量frame
是用来决定你将每一秒视频转化为多少张图片的参数。然后os.system()那句话就是让你的Windows在cmd里面执行里面那句话,大致的意思就是以10帧每秒的频率提取该视频的图片,保存到你的目录。具体用法可以百度ffmpeg,这个有点麻烦,就不细说了。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
from PIL import Image # 如果没有该库,请 pip install PIL
import numpy # 如果没有该库,请 pip install numpy
frame = 10 # 每秒10帧, 即一秒十张
def get_image(video_path, image_path):
try:
os.system('ffmpeg -i {0} -r {1} -f image2 {2}\%05d.png'.format(video_path, frame, image_path))
except:
print('ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
然后我们提取到了图片,去image
文件夹下去看,可以看到很多图片
接下来,是将图片转化为txt文件,写的函数是image_to_txt(image_path, txt_path)
,这里的两个参数分别是你读取图片的路径和存放txt文件的路径,代码解释放在注释当中了。
def image_to_txt(image_path, txt_path):
txt_count = 1 # 用于命名txt文件
fileList = os.listdir(image_path) # 返回所有图片名称,是个字符串列表
for file in fileList: # 遍历每一张图片
img = Image.open(image_path + '\\'+ file).convert('L')
# 这里使用到PIL库convert函数,将RGB图片转化为灰度图,参数'L'代表转化为灰度图
charWidth = 140
# 这个是设置你后面在cmd里面显示内容的窗口大小,请根据自己的情况,适当调整值
img = img.resize((charWidth, 40))
target_width, target_height = img.size
data = numpy.array(img)[:target_height, :target_width]
# 使用numpy库,将图像转化为数组
with open(txt_path + '\\' + str(txt_count) + '.txt', 'w', encoding='utf-8') as f:
txt_count += 1 # 一张图对应一个txt文件,所以每遍历一张图,该值加一
for row in data:
for pixel in row:
if pixel < 127: # 如果灰度值小于127,也就是偏黑的,就写一个字符 '*'
f.write('*')
else:
f.write(' ')
f.write('\n')
这是txt
文件夹的结果:
最后就是,一个run(txt_path)
函数,用于“播放”这些txt文件,同样的参数是txt文件的路径
def run(txt_path):
fileList = os.listdir(txt_path)
for i in range(1, len(fileList)+1): # 遍历所有的txt文件
try:
os.system('type ' + txt_path + '\\' + str(i) + '.txt')
# 这里type命令是Windows下的命令,相信很多人没怎么用过,你试一下就知道,type+文件名,就可以在cmd里面显示文件内容
os.system('cls')
# 清屏的意思,每显示一次txt文件,就清屏,然后显示下一个txt
# 这里还可以适当的加延时函数,如果显示的太快的话
except:
print('ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
最后的最后:让这三个函数跑起来~~
if __name__ == '__main__':
video_path = r'你的视频路径'
image_path = r'你存储图片的路径'
txt_path = r'你存储txt文件的路径'
get_image(video_path, image_path)
image_to_txt(image_path, txt_path)
run(txt_path)
总结:
这个代码不具有什么实用性,纯属有点好玩,再加上可以练习python,没事的时候可以玩一玩。还有处理的视频最好是颜色单一的,然后人物形象颜色也要单一,这样找那个阈值比较好找。所以我这里直接找了黑白的图,如果颜色及较多又分散的话,最后的效果也不是很好。
记第一次写博客,完。