1. 程式人生 > >超不清視頻播放器-用Python將視頻轉成字符

超不清視頻播放器-用Python將視頻轉成字符

wrap 控制 替換字符 clas 處理 link 生成 組成 data-

前言

今天分享的這段代碼,看起來沒啥實際用處,而且有些反潮流,因為現如今大家看視頻都追求更高分辨率的超清畫質,而我們這個,是一個“超不清”的視頻播放器:在控制臺裏播放視頻,用字符來表示畫面

不過我覺得它至少可以有三個作用:1.用來練習視頻和圖像處理的編程開發;2.在沒有圖形界面的服務器上播放視頻(雖然效果不咋地);3.作為一種獨特的藝術風格化處理

原理

程序的原理其實很簡單,關鍵是你要理解計算機中一張圖像的組成:一堆像素點。我們平常說的 1920*1080 之類的分辨率,也就是指這個像素點的多少。我們想做成字符畫,也就是考慮如何用不同的字符來表示一個像素。

通常一個像素點由3個0~255的值表示

,分別表示紅、綠、藍三種顏色值,值越大表示顏色越深。但字符畫是沒有顏色的,所以需要將圖像轉成灰度圖,這樣就可以跟一組從深到淺的字符形成一種對應關系。比如深的點就是 @,淺色的點就是 .。

一幅圖像全部轉成字符序列後,就可以直接在控制臺輸出了。對於一個視頻來說,只需要將每一幀都轉換後輸出,並按照一定的時間間隔清屏、輸出下一幀,即可達到我們的需要的效果。

效果

技術分享圖片

技術分享圖片技術分享圖片

技術分享圖片

代碼

# coding: utf8
import cv2 as cv
import os
import time
# 替換字符列表
ascii_char = list(r"$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`‘. 
") char_len = len(ascii_char) # 加載視頻 cap = cv.VideoCapture(video.mp4) while True: # 讀取視頻每一幀 hasFrame, frame = cap.read() if not hasFrame: break # 視頻長寬 width = frame.shape[0] height = frame.shape[1] # 轉灰度圖 img_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# 縮小圖片並調整長寬比 img_resize = cv.resize(img_gray, (int(width / 10), int(height / 10))) text = ‘‘ # 遍歷圖片中的像素 for row in img_resize: for pixel in row: # 根據像素值,選取對應的字符 text += ascii_char[int(pixel / 256 * char_len)] text += \n # 清屏 os.system(cls) # mac是‘clear‘ # 輸出生成的字符方陣 print(text) # 適當暫停一下 time.sleep(0.03)

代碼不長,稍微解釋下其中幾處:

  1. ascii_char 這個字符序列並不是必須這樣,只要大致上滿足其中的字符看起來從深到淺即可,字符越多越準確,效果就越好。
  2. 讀取視頻使用了 opencv-python,並直接用它提供的方法轉了灰度圖,在之前的文章中也有過介紹:OpenCV-Python,計算機視覺開發利器
  3. resize 這一步比較重要,因為有的視頻分辨率很高,直接一個像素轉一個字符的話量太大,所以先縮小圖片。另一個原因是字符一般都不是正方形,所以在圖片長寬比上要做一定的調整,這樣最終效果比較好。(實際中要根據你自己控制臺中的字體效果來調整縮放比例)
  4. ascii_char[int(pixel / 256 * char_len)] 是整個轉換的核心,因為一個像素的顏色範圍是 0~255,通過 pixel / 256 * char_len 可以將一個像素值對應於字符序列中灰度相當的字符
  5. 關於輸出,有幾個值得註意的點:輸出一幀前需要清屏,不同平臺命令有區別。

補充

這種方法易受其它因素的影響,比如視頻內容,間隔時間,放縮比例等。

也可以通過如下方式體驗:

  1. 打開你的命令行
  2. 輸入 curl aoaoao.me:1926
  3. 回車

感受時間的流逝吧!(明白的自然明白)

參考鏈接:

1、https://zhuanlan.zhihu.com/p/53881072

2、什麽是SCII視頻流服務

超不清視頻播放器-用Python將視頻轉成字符