最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

用Python字符畫出了一個(gè)谷愛凌

 更新時(shí)間:2022年02月16日 10:58:46   作者:算法碼上來(lái)  
之前經(jīng)常在網(wǎng)上看到那種由一個(gè)個(gè)字符構(gòu)成的視頻,非常炫酷。本文也將利用Python字符畫一個(gè)最近的冬奧冠軍谷愛凌,感興趣的小伙伴可以學(xué)習(xí)一下

之前經(jīng)常在網(wǎng)上看到那種由一個(gè)個(gè)字符構(gòu)成的視頻,非常炫酷。一直不懂是怎么做的,這兩天研究了一下,發(fā)現(xiàn)并不難。

先來(lái)看一個(gè)最終效果(如果模糊的話,點(diǎn)擊下方鏈接看高清版):

https://pan.baidu.com/s/1DvedXlDZ4dgHKLogdULogg 提取碼:1234

怎么實(shí)現(xiàn)的?

簡(jiǎn)單來(lái)說(shuō),要將一個(gè)彩色的視頻變成字符畫出來(lái)的黑白視頻,用下面幾步就能搞定:

  1. 對(duì)原視頻進(jìn)行抽幀,對(duì)每一幀黑白化,并將像素點(diǎn)用對(duì)應(yīng)的字符表示。
  2. 將表示出來(lái)的字符串再重新組合成字符圖像。
  3. 將所有的字符圖像再組合成字符視頻。
  4. 將原視頻的音頻導(dǎo)入到新的字符視頻中。

運(yùn)行方法

完整的代碼我放在文章末尾了,直接運(yùn)行python3 video2char.py即可。程序會(huì)要求你輸入視頻的本地路徑和轉(zhuǎn)變后的清晰度(0最模糊,1最清晰。當(dāng)然越清晰,轉(zhuǎn)變?cè)铰?/p>

運(yùn)行代碼的話需要用到tqdm、opencv_python、moviepy等幾個(gè)庫(kù),首先得pip3 install確保它們都有了。

原理分析

這里面最關(guān)鍵的步驟就是如何將一幀彩色圖像轉(zhuǎn)變?yōu)楹诎椎淖址麍D像,如下圖所示:

從青蛙公主視頻抽幀出來(lái)的

用字符畫出來(lái)的

而轉(zhuǎn)變的原理其實(shí)很簡(jiǎn)單。首先因?yàn)橐粋€(gè)字符畫在圖像里會(huì)占據(jù)很大一個(gè)像素塊,所以必須先對(duì)彩色圖像進(jìn)行壓縮,連續(xù)的一個(gè)像素塊可以合并,這個(gè)壓縮過程就是opencv的resize操作。

然后將壓縮后的像素點(diǎn)轉(zhuǎn)變?yōu)楹诎紫袼攸c(diǎn),并轉(zhuǎn)變?yōu)閷?duì)應(yīng)的字符。字符的話我這里采用的是下面的字符串,從黑到白,經(jīng)過我的實(shí)踐這一組是效果最好的:

"#8XOHLTI)i=+;:,. "

接著就需要將轉(zhuǎn)變后的字符畫到新的畫布上去,需要注意的點(diǎn)是排布得均勻緊湊了,畫布四周最好不要有太多多余的空白。

最后把所有的字符圖像合并成視頻就行了,但是合并后是沒有聲音的,需要用moviepy庫(kù)把原視頻的聲音導(dǎo)入過來(lái)。

完整代碼

import os
import re
import shutil
from tqdm import trange, tqdm
import cv2
from PIL import Image, ImageFont, ImageDraw
from moviepy.editor import VideoFileClip
 
 
class V2Char:
    font_path = "Arial.ttf"
    ascii_char = "#8XOHLTI)i=+;:,. "
 
    def __init__(self, video_path, clarity):
        self.video_path = video_path
        self.clarity = clarity
 
    def video2str(self):
        def convert(img):
            if img.shape[0] > self.text_size[1] or img.shape[1] > self.text_size[0]:
                img = cv2.resize(img, self.text_size, interpolation=cv2.INTER_NEAREST)
            ascii_frame = ""
            for i in range(img.shape[0]):
                for j in range(img.shape[1]):
                    ascii_frame += self.ascii_char[
                        int(img[i, j] / 256 * len(self.ascii_char))
                    ]
            return ascii_frame
 
        print("正在將原視頻轉(zhuǎn)為字符...")
        self.char_video = []
        cap = cv2.VideoCapture(self.video_path)
        self.fps = cap.get(cv2.CAP_PROP_FPS)
        self.nframe = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        self.raw_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        self.raw_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
        font_size = int(25 - 20 * max(min(float(self.clarity), 1), 0))
        self.font = ImageFont.truetype(self.font_path, font_size)
        self.char_width, self.char_height = max(
            [self.font.getsize(c) for c in self.ascii_char]
        )
        self.text_size = (
            int(self.raw_width / self.char_width),
            int(self.raw_height / self.char_height),
        )
        for _ in trange(self.nframe):
            raw_frame = cv2.cvtColor(cap.read()[1], cv2.COLOR_BGR2GRAY)
            frame = convert(raw_frame)
            self.char_video.append(frame)
        cap.release()
 
    def str2fig(self):
        print("正在生成字符圖像...")
        col, row = self.text_size
        catalog = self.video_path.split(".")[0]
        if not os.path.exists(catalog):
            os.makedirs(catalog)
        blank_width = int((self.raw_width - self.text_size[0] * self.char_width) / 2)
        blank_height = int((self.raw_height - self.text_size[1] * self.char_height) / 2)
        for p_id in trange(len(self.char_video)):
            strs = [self.char_video[p_id][i * col : (i + 1) * col] for i in range(row)]
            im = Image.new("RGB", (self.raw_width, self.raw_height), (255, 255, 255))
            dr = ImageDraw.Draw(im)
            for i, str in enumerate(strs):
                for j in range(len(str)):
                    dr.text(
                        (
                            blank_width + j * self.char_width,
                            blank_height + i * self.char_height,
                        ),
                        str[j],
                        font=self.font,
                        fill="#000000",
                    )
            im.save(catalog + r"/pic_{}.jpg".format(p_id))
 
    def jpg2video(self):
        print("正在將字符圖像合成字符視頻...")
        catalog = self.video_path.split(".")[0]
        images = os.listdir(catalog)
        images.sort(key=lambda x: int(re.findall(r"\d+", x)[0]))
        im = Image.open(catalog + "/" + images[0])
        fourcc = cv2.VideoWriter_fourcc("m", "p", "4", "v")
        savedname = catalog.split("/")[-1]
        vw = cv2.VideoWriter(savedname + "_tmp.mp4", fourcc, self.fps, im.size)
        for image in tqdm(images):
            frame = cv2.imread(catalog + "/" + image)
            vw.write(frame)
        vw.release()
        shutil.rmtree(catalog)
 
    def merge_audio(self):
        print("正在將音頻合成到字符視頻中...")
        raw_video = VideoFileClip(self.video_path)
        char_video = VideoFileClip(self.video_path.split(".")[0] + "_tmp.mp4")
        audio = raw_video.audio
        video = char_video.set_audio(audio)
        video.write_videofile(
            self.video_path.split(".")[0] + f"_{self.clarity}.mp4",
            codec="libx264",
            audio_codec="aac",
        )
        os.remove(self.video_path.split(".")[0] + "_tmp.mp4")
 
    def gen_video(self):
        self.video2str()
        self.str2fig()
        self.jpg2video()
        self.merge_audio()
 
 
if __name__ == "__main__":
    video_path = input("輸入視頻文件路徑:\n")
    clarity = input("輸入清晰度(0~1, 直接回車使用默認(rèn)值0):\n") or 0
    v2char = V2Char(video_path, clarity)
    v2char.gen_video()

以上就是用Python字符畫出了一個(gè)谷愛凌的詳細(xì)內(nèi)容,更多關(guān)于Python字符畫的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python logging日志模塊使用指南

    Python logging日志模塊使用指南

    Python 的 logging 模塊提供了標(biāo)準(zhǔn)的日志接口,可以通過它存儲(chǔ)各種格式的日志,日志記錄提供了一組便利功能,用于簡(jiǎn)單的日志記錄用法,本文就給大家簡(jiǎn)單的介紹一下Python logging日志模塊使用方法,需要的朋友可以參考下
    2023-08-08
  • Python的Django框架中從url中捕捉文本的方法

    Python的Django框架中從url中捕捉文本的方法

    這篇文章主要介紹了Python的Django框架中從url中捕捉文本的方法,以及URLconf搜索的一些相關(guān)情況,需要的朋友可以參考下
    2015-07-07
  • 詳解python中的文件與目錄操作

    詳解python中的文件與目錄操作

    這篇文章主要介紹了詳解python中的文件與目錄操作的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • 詳解如何從TensorFlow的mnist數(shù)據(jù)集導(dǎo)出手寫體數(shù)字圖片

    詳解如何從TensorFlow的mnist數(shù)據(jù)集導(dǎo)出手寫體數(shù)字圖片

    這篇文章主要介紹了詳解如何從TensorFlow的mnist數(shù)據(jù)集導(dǎo)出手寫體數(shù)字圖片,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Django中使用SMTP實(shí)現(xiàn)郵件發(fā)送功能

    Django中使用SMTP實(shí)現(xiàn)郵件發(fā)送功能

    在?Django?中使用?SMTP?發(fā)送郵件是一個(gè)常見的需求,通常用于發(fā)送用戶注冊(cè)確認(rèn)郵件、密碼重置郵件等,下面我們來(lái)看看如何在?Django?中配置?SMTP?發(fā)送郵件吧
    2025-01-01
  • django API 中接口的互相調(diào)用實(shí)例

    django API 中接口的互相調(diào)用實(shí)例

    這篇文章主要介紹了django API 中接口的互相調(diào)用實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2020-04-04
  • Python實(shí)現(xiàn)文字pdf轉(zhuǎn)換圖片pdf效果

    Python實(shí)現(xiàn)文字pdf轉(zhuǎn)換圖片pdf效果

    當(dāng)我們把word轉(zhuǎn)化為pdf,wps默認(rèn)轉(zhuǎn)化為文字pdf,而圖片pdf要會(huì)員。所以本文將通過Python語(yǔ)言實(shí)現(xiàn)文字pdf轉(zhuǎn)換圖片pdf,需要的可以參考一下
    2022-04-04
  • Python 如何優(yōu)雅的將數(shù)字轉(zhuǎn)化為時(shí)間格式的方法

    Python 如何優(yōu)雅的將數(shù)字轉(zhuǎn)化為時(shí)間格式的方法

    這篇文章主要介紹了Python 如何優(yōu)雅的將數(shù)字轉(zhuǎn)化為時(shí)間格式的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Django Auth用戶認(rèn)證組件實(shí)現(xiàn)代碼

    Django Auth用戶認(rèn)證組件實(shí)現(xiàn)代碼

    這篇文章主要介紹了Django Auth用戶認(rèn)證組件實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • python最小生成樹kruskal與prim算法詳解

    python最小生成樹kruskal與prim算法詳解

    這篇文章主要為大家詳細(xì)介紹了python最小生成樹kruskal與prim算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01

最新評(píng)論

徐水县| 宁陕县| 温泉县| 四会市| 大英县| 凤庆县| 津南区| 普安县| 洪雅县| 新密市| 长乐市| 四子王旗| 故城县| 木里| 英德市| 缙云县| 贵南县| 姜堰市| 汶川县| 景东| 桐城市| 仁怀市| 嘉荫县| 名山县| 太仆寺旗| 平陆县| 盖州市| 台安县| 从江县| 福安市| 乐昌市| 华宁县| 敖汉旗| 历史| 江孜县| 三门县| 古丈县| 含山县| 樟树市| 噶尔县| 泊头市|