python圖像轉字符畫需要用到matplotlib.pyplot庫,視頻轉字符畫需要用到opencv庫,這里的代碼基於python 3.5
圖像轉字符畫需要先將圖像轉為灰度圖,轉灰度圖的公式是 gray = 0.2126 * r + 0.7152 * g + 0.0722 * b,因為matplotlib圖像的色彩排序是RGB的(opencv是BGR),所以如果不用庫函數,可以使用以下代碼實現灰度轉換:
gray = 0.2126 * pic[:,:,0] + 0.7152 * pic[:,:,1] + 0.0722 * pic[:,:,2]
轉成灰度圖以后,對於每一個像素值,都要對應一個字符值。然后從圖像中均勻取一些像素出來作映射即可實現圖像到字符畫的轉換,代碼如下:
import matplotlib.pyplot as plt show_heigth = 30 show_width = 40 #這兩個數字是調出來的 ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ") #生成一個ascii字符列表 char_len = len(ascii_char) pic = plt.imread("wm.jpg") #使用plt.imread方法來讀取圖像,對於彩圖,返回size = heigth*width*3的圖像 #matplotlib 中色彩排列是R G B #opencv的cv2中色彩排列是B G R pic_heigth,pic_width,_ = pic.shape #獲取圖像的高、寬 gray = 0.2126 * pic[:,:,0] + 0.7152 * pic[:,:,1] + 0.0722 * pic[:,:,2] #RGB轉灰度圖的公式 gray = 0.2126 * r + 0.7152 * g + 0.0722 * b #思路就是根據灰度值,映射到相應的ascii_char for i in range(show_heigth): #根據比例映射到對應的像素 y = int(i * pic_heigth / show_heigth) text = "" for j in range(show_width): x = int(j * pic_width / show_width) text += ascii_char[int(gray[y][x] / 256 * char_len)] print(text)
效果:
對於視頻,其實也就是將每一幀轉成字符畫,這里用opencv來讀取視頻的每一幀。
如果沒有裝opencv庫的話,可以先去https://www.lfd.uci.edu/~gohlke/pythonlibs/下載對應版本的opencv,然后安裝
如果遇到numpy core的問題,可以更新一下numpy。
為了有更好的顯示效果,先將每一幀的轉換的字符畫保存下來,最后再統一輸出出去。
import cv2 import os show_heigth = 30 show_width = 80 ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ") #生成一個ascii字符列表 char_len = len(ascii_char) vc = cv2.VideoCapture("v.mkv") #加載一個視頻 if vc.isOpened(): #判斷是否正常打開 rval , frame = vc.read() else: rval = False frame_count = 0 outputList = [] #初始化輸出列表 while rval: #循環讀取視頻幀 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #使用opencv轉化成灰度圖 gray = cv2.resize(gray,(show_width,show_heigth))#resize灰度圖 text = "" for pixel_line in gray: for pixel in pixel_line: #字符串拼接 text += ascii_char[int(pixel / 256 * char_len )] text += "\n" outputList.append(text) frame_count = frame_count + 1 if frame_count % 100 == 0: print("已處理" + str(frame_count) + "幀") rval, frame = vc.read() print("處理完畢") for frame in outputList: os.system("cls") #清屏 print(frame) print() print()
這里用的bad apple的視頻來進行轉換: