python視頻轉化字節(jié)問題的完整實現
廢話不多說,直接開干!
抖音字符視頻在今年火過一段時間。
反正我是始終忘不了那段劉耕宏老師本草綱目的音樂…
這一次自己也來實現一波,做一個字符視頻出來
百度好多都是顯示模塊,這個完整實現效果
步驟
將視頻轉化為一幀一幀的圖片
把圖片轉化為字符畫
按順序播放字符畫
1、準備
安裝 Python-OpenCV 庫
安裝 Numpy 科學計算庫
用到模塊庫
import time import cv2 import os from PIL import Image, ImageDraw, ImageFont import numpy as np import os
然后新建python代碼文檔,在開頭添加上下面的導入語句
2. 材料
材料來個視頻文件了,我這里用的是zimeng.mp4,下載下來和代碼放到同一目錄下
你也可以換成自己的,建議是學習時盡量選個短一點的視頻,十幾秒十秒就行了,方便調試用
此外,要選擇對比度高的視頻。否則的話,就需要彩色字符才能有足夠好的表現,有時間我試試。
3、按幀讀取視頻
現在繼續(xù)添加代碼,實現第一步:按幀讀取視頻。
下面這個函數,接受視頻路徑和字符視頻的尺寸信息,返回一個img列表,其中的img是尺寸都為指定大小的灰度圖。
第一步截取圖片
def video_img(file='zimeng.mp4'):
# 在當前目錄下新建文件夾
folder_path = "img_bear/"
if folder_path:
pass
else:
os.makedirs(folder_path)
# 進行視頻的載入
vc = cv2.VideoCapture(file)
# 判斷載入的視頻是否可以打開
ret = vc.isOpened()
# 循環(huán)讀取視頻幀
num = 0
while ret:
num = num + 1
# 進行單張圖片的讀取,ret的值為True或者Flase,frame表示讀入的圖片
ret, frame = vc.read()
if ret:
# 存儲為圖像
cv2.imwrite('img_bear/' + str(num) + '.jpg', frame)
# 輸出圖像名稱
print('img_bear/' + str(num) + '.jpg')
# 在一個給定的時間內(單位ms)等待用戶按鍵觸發(fā),1ms
cv2.waitKey(1)
else:
break
# 視頻釋放
vc.release()
time.sleep(0.5)
video_image(num)
如果運行沒報錯,就沒問題
代碼里的注釋應該寫得很清晰了,繼續(xù)下一步
第二步對圖片做灰度處理
視頻轉換成了圖像,這一步便是把圖像轉換成字符畫
上面這個函數,一個img對象為參數,前往對應的字符畫
def video_image(num=''):
# 創(chuàng)建字符圖片文件夾
folder_path = "bear/"
if folder_path:
pass
else:
os.makedirs(folder_path)
for i in range(1, num):
filename = 'img_bear/' + str(i) + '.jpg'
im = Image.open(filename) # 返回一個Image對象
width = im.size[0]
heigth = im.size[1]
print('寬:%d,高:%d' % (im.size[0], im.size[1]))
# 字符列表
ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~ <>i!lI;:,\"^`'. ")
# 判斷圖片是否存在
if os.path.exists(filename):
# 將圖片轉化為灰度圖像,并重設大小
img_array = np.array(Image.open(filename).resize((160, 160), Image.ANTIALIAS).convert('L'))
# 創(chuàng)建新的圖片對象
img = Image.new('L', (width, heigth), 255)
draw_object = ImageDraw.Draw(img)
# 設置字體
font = ImageFont.truetype('consola.ttf', 10, encoding='unic')
# 根據灰度值添加對應的字符
for j in range(160):
for k in range(160):
x, y = k * 8, j * 8
index = int(img_array[j][k] / 4)
draw_object.text((x, y), ascii_char[index], font=font, fill=0)
name = 'bear/' + str(i) + '.jpg'
print(name)
# 保存字符圖片
img.save(name, 'JPEG')
time.sleep(0.5)
video(num)
第三步字符轉視頻
寫了這么多代碼,如今終于要出效果了。如今就是最激動人心的一步:播放字符畫了。
異樣的,我把它封裝成了一個函數。上面這個函數承受一個字符畫的列表并播放。
def video(num):
filename = 'img_bear/' + str(1) + '.jpg'
im = Image.open(filename) # 返回一個Image對象
width = im.size[0]
heigth = im.size[1]
# 設置視頻編碼器,這里使用使用MJPG編碼器
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
# 輸出視頻參數設置,包含視頻文件名、編碼器、幀率、視頻寬高(此處參數需和字符圖片大小一致)
videoWriter = cv2.VideoWriter('bear_character.avi', fourcc, 20.0, (width, heigth))
for i in range(1, num):
filename = 'bear/'+str(i)+'.jpg'
# 判斷圖片是否存在
if os.path.exists(filename):
img = cv2.imread(filename=filename)
# 在一個給定的時間內(單位ms)等待用戶按鍵觸發(fā),100ms
cv2.waitKey(100)
# 將圖片寫入視頻中
videoWriter.write(img)
print(str(i) + '.jpg' + ' done!')
# 視頻釋放
videoWriter.release()
time.sleep(1)
# 刪除圖片
remove_img()
remove_img_bear()
下面完整代碼
可能要等很久。我使用示例視頻大概需要 500 秒左右。
ctrl+f10執(zhí)行對應的文件
完整代碼里面加了
執(zhí)行生成圖片,生成灰度圖片,最后通過灰度生成字節(jié)視頻刪除多余文件
說了那太多廢話就是:最后還需刪除一些臨時的文件及文件夾。
import time
import cv2
import os
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import os
# 第一步截取圖片
def video_img(file='zimeng.mp4'):
# 在當前目錄下新建文件夾
folder_path = "img_bear/"
if folder_path:
pass
else:
os.makedirs(folder_path)
# 進行視頻的載入
vc = cv2.VideoCapture(file)
# 判斷載入的視頻是否可以打開
ret = vc.isOpened()
# 循環(huán)讀取視頻幀
num = 0
while ret:
num = num + 1
# 進行單張圖片的讀取,ret的值為True或者Flase,frame表示讀入的圖片
ret, frame = vc.read()
if ret:
# 存儲為圖像
cv2.imwrite('img_bear/' + str(num) + '.jpg', frame)
# 輸出圖像名稱
print('img_bear/' + str(num) + '.jpg')
# 在一個給定的時間內(單位ms)等待用戶按鍵觸發(fā),1ms
cv2.waitKey(1)
else:
break
# 視頻釋放
vc.release()
time.sleep(0.5)
video_image(num)
# 第二步對圖片做灰度處理
def video_image(num=''):
# 創(chuàng)建字符圖片文件夾
folder_path = "bear/"
if folder_path:
pass
else:
os.makedirs(folder_path)
for i in range(1, num):
filename = 'img_bear/' + str(i) + '.jpg'
im = Image.open(filename) # 返回一個Image對象
width = im.size[0]
heigth = im.size[1]
print('寬:%d,高:%d' % (im.size[0], im.size[1]))
# 此字符表用于生字符幀,對應256個像素,字符越多且不同樣式,字符幀越精細
ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~ <>i!lI;:,\"^`'. ")
# 判斷圖片是否存在
if os.path.exists(filename):
# 將圖片轉化為灰度圖像,并重設大小
img_array = np.array(Image.open(filename).resize((160, 160), Image.ANTIALIAS).convert('L'))
# 創(chuàng)建新的圖片對象
img = Image.new('L', (width, heigth), 255)
draw_object = ImageDraw.Draw(img)
# 設置字體
font = ImageFont.truetype('consola.ttf', 10, encoding='unic')
# 根據灰度值添加對應的字符
for j in range(160):
for k in range(160):
x, y = k * 8, j * 8
index = int(img_array[j][k] / 4)
draw_object.text((x, y), ascii_char[index], font=font, fill=0)
name = 'bear/' + str(i) + '.jpg'
print(name)
# 保存字符圖片
img.save(name, 'JPEG')
time.sleep(0.5)
video(num)
# 第三步字符轉視頻
def video(num):
filename = 'img_bear/' + str(1) + '.jpg'
im = Image.open(filename) # 返回一個Image對象
width = im.size[0]
heigth = im.size[1]
# 設置視頻編碼器,這里使用使用MJPG編碼器
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
# 輸出視頻參數設置,包含視頻文件名、編碼器、幀率、視頻寬高(此處參數需和字符圖片大小一致)
videoWriter = cv2.VideoWriter('bear_character.avi', fourcc, 20.0, (width, heigth))
for i in range(1, num):
filename = 'bear/'+str(i)+'.jpg'
# 判斷圖片是否存在
if os.path.exists(filename):
img = cv2.imread(filename=filename)
# 在一個給定的時間內(單位ms)等待用戶按鍵觸發(fā),100ms
cv2.waitKey(100)
# 將圖片寫入視頻中
videoWriter.write(img)
print(str(i) + '.jpg' + ' done!')
# 視頻釋放
videoWriter.release()
time.sleep(1)
# 刪除圖片
remove_img()
remove_img_bear()
# 原圖片刪除
def remove_img():
files = os.getcwd() # files中保存的是當前的執(zhí)行目錄
file_name = files + "/img_bear"
del_list = os.listdir(file_name)
for f in del_list:
file_path = os.path.join(file_name, f)
print(file_path)
if os.path.isfile(file_path):
os.remove(file_path)
print('成功刪除文件:')
else:
print('未找到此文件:')
# 灰度圖片刪除
def remove_img_bear():
files = os.getcwd() # files中保存的是當前的執(zhí)行目錄
file_name = files + "/bear"
del_list = os.listdir(file_name)
for f in del_list:
file_path = os.path.join(file_name, f)
print(file_path)
if os.path.isfile(file_path):
os.remove(file_path)
print('成功刪除文件:')
else:
print('未找到此文件:')
def main():
video_img('video.mp4')
if __name__ == "__main__":
main()
進一步優(yōu)化
到了這里,核心功能基本都完成了。
不過仔細想想,其實還有很多可以做的:
什么是指定要轉換的區(qū)間、幀率?
每次轉換都要很久的時間,能不能邊轉換邊播放?或者轉換后把數據保存起來,下次播放時,就直接讀緩存
看下效果圖


總結
到此這篇關于python視頻轉化字節(jié)問題的文章就介紹到這了,更多相關python視頻轉化字節(jié)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python3+SQLAlchemy+Sqlite3實現ORM教程
這篇文章主要介紹了Python3+SQLAlchemy+Sqlite3實現ORM教程,需要的朋友可以參考下2021-02-02
利用Python實現原創(chuàng)工具的Logo與Help
這篇文章主要給大家介紹了關于如何利用Python實現原創(chuàng)工具的Logo與Help的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考借鑒,下面來一起看看吧2018-12-12

