「ASCII Art」字符畫黑人抬棺

馬上,我就將迎來小學(xué)的最后一個六一節(jié)日,不管怎么說,我也得整個節(jié)目。再加上這次節(jié)目是錄制形式的,這使得我可以以編程作為節(jié)目主體。

稍加思考,我就想到了可以做字符畫黑人抬棺。

有關(guān)這一項目的信息,可以參考README

README

Dancing_Pallbearers_ASCII

以上為GitHub Repo名稱

Play video "Dancing Pallbearers" in ASCII Art.

How To Use

  1. Download original video (.mp4) from Bilibili or other websites.

  2. Put it in the same directory as the source code.

  3. Run Extract_Frames.py. It will generate frame0.jpg, frame1.jpg, etc.

  4. Run Main.py. Windows Terminal is recommended.

Using this source code, can I play other videos?

Of Course, You Can.

It is worth noting that maybe you should change some value in line 23 in Main.py.

Other

This source code is for my Children's day program.

If you're interested in this program, There's a link.

代碼分析

接下來,對代碼進行簡要的介紹。

# Extract_Frames.py
import cv2

vidcap = cv2.VideoCapture('黑人抬棺.mp4')
success, image = vidcap.read()
count = 0
success = True
while success:
    success, image = vidcap.read()
    cv2.imwrite("frame%d.jpg" % count, image)
    if cv2.waitKey(10) == 27:
        break
    count += 1

以上代碼,用于輸出黑人抬棺視頻的每一幀畫面,代碼技術(shù)含量并不高,只要求對cv2庫有一定了解。

每幀畫面
# Main.py
from PIL import Image
import os

os.system("color 70")
ascii_char = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. "


def transform(image_file):
    image_file = image_file.convert("L")
    char = ""
    for h in range(0, image_file.size[1]):
        for w in range(0, image_file.size[0]):
            gray = image_file.getpixel((w, h))
            char += ascii_char[int((len(ascii_char) * gray) / 256)]
        char += "\n"
    return char


for i in range(0, 1323):
    os.system("cls")
    pic = open(u"frame" + str(i) + ".jpg", "rb")
    pic = Image.open(pic)
    pic = pic.resize((int(pic.size[0] * 0.08), int(pic.size[1] * 0.04)))
    print(transform(pic))

這里是主程序,首先用os.system("color 70")更改終端背景顏色為白色,保證用戶看到的字符畫視頻不是顏色相反的效果。

接下來,定義transform類,用于把圖片轉(zhuǎn)為字符畫。

image_file = image_file.convert("L")將照片文件轉(zhuǎn)化為了黑白照片,以方便獲取灰度值。

    for h in range(0, image_file.size[1]):
        for w in range(0, image_file.size[0]):

嵌套for循環(huán),遍歷圖片的每一個像素點。

gray = image_file.getpixel((w, h))獲取像素點的灰度值。

char += ascii_char[int((len(ascii_char) * gray) / 256)]將灰度值轉(zhuǎn)化為了字符。

這里有必要提一下,在此之前,我以為是要將字符轉(zhuǎn)化為圖片,獲取灰度值,然后與像素點的灰度值相匹配,其實并沒有這么麻煩。我們往前看,在定義ascii_char的時候,ascii_char = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^'. "這些字符,其實是按照灰度值高到灰度值低的順序排列的,那么根據(jù)像素灰度值就可以直接計算字符在字符串中的位置。

接下來,遍歷每一幀畫面,進行顯示。

os.system("cls")為清屏指令,為顯示下一幀畫面做準(zhǔn)備。

pic = pic.resize((int(pic.size[0] * 0.08), int(pic.size[1] * 0.04)))這里對圖片進行了縮放操作,原因有兩個:

  1. 肉眼無法分辨的像素點被放大到了字符大小,為了適應(yīng)屏幕,需要縮小

  2. 正方形的像素點變?yōu)榱碎L方形,所以會將寬度縮小到長的一般,大致能使圖像顯示正常

那么,全部程序就完工了,如果需要將圖片轉(zhuǎn)化為字符畫,可以直接調(diào)用transform方法,當(dāng)然,要按照程序for循環(huán)中的方式打開圖片,并不是傳遞給函數(shù)圖片的名稱。

此程序還有一些缺陷,最主要的是,將圖片轉(zhuǎn)化為字符畫的過程需要一定時間,這使得在播放過程中會有空白畫面的存在,我目前想到的解決方式,就是把os.system("cls")放到方法的return前面,但是為了保證程序的模塊化和方便調(diào)用,并沒有使用這一方法。

最終效果可以前往README中的鏈接查看。


在我的博客上查看本文

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容