python趣味代码之ffmpeg实现视频转码+cmd动画效果

背景:

这篇博客是我看到一个视频,使用python实现的一个趣味代码,然后就自己尝试实现了一下,以此记录一下整个过程。

内容:

主要实现的内容就是使用mmfpeg这个工具,实现对视频的读取,然后从视频中按照一定的帧率提取出来照片,再将这些照片转化为灰度图像,设定合适的阈值,找到符合阈值的灰度值的位置。
首先给大家看一下结果,然后再一步一步说明怎么实现的:
1. 这是在网上找的一个GIF图,然后转成MP4视频
这里写图片描述
2. 运行结果如下(博客好像不能插入视频,我就截了几张图):
这里写图片描述
这里写图片描述
这里写图片描述

  1. 前期准备:
    首先要下载ffmpeg,这里只说Windows下的方式(linux不难),首先去官网,下载Windows版本的安装包
    这里写图片描述

    下载完成后,解压,放到你喜欢的位置,然后找到目录下的bin文件夹,将该目录放到你的环境变量中(如何配置环境变量这里不细说,百度之。)
    这里写图片描述

    之后就是测试一下有没有配置成功,打开你的cmd,输入ffmpeg -version,输出以下东西,就是成功了
    这里写图片描述

  2. 目录结构

    我们的思路是视频——>图片——>txt文件,再“播放”这些txt文件。所以在你的工作目录下要放2个文件夹imagetxt,分别存放图像和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,没事的时候可以玩一玩。还有处理的视频最好是颜色单一的,然后人物形象颜色也要单一,这样找那个阈值比较好找。所以我这里直接找了黑白的图,如果颜色及较多又分散的话,最后的效果也不是很好。

记第一次写博客,完。

猜你喜欢

转载自blog.csdn.net/pandawangyt/article/details/80266304
今日推荐