程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python趣味代碼之ffmpeg實現視頻轉碼+cmd動畫效果

編輯:Python

背景:

這篇博客是我看到一個視頻,使用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,沒事的時候可以玩一玩。還有處理的視頻最好是顏色單一的,然後人物形象顏色也要單一,這樣找那個阈值比較好找。所以我這裡直接找了黑白的圖,如果顏色及較多又分散的話,最後的效果也不是很好。

記第一次寫博客,完。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved