欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

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

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

  1. 對(duì)原視頻進(jìn)行抽幀,對(duì)每一幀黑白化,并將像素點(diǎn)用對(duì)應(yīng)的字符表示。
  2. 將表示出來的字符串再重新組合成字符圖像。
  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è)庫,首先得pip3 install確保它們都有了。

原理分析

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

從青蛙公主視頻抽幀出來的

用字符畫出來的

而轉(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庫把原視頻的聲音導(dǎo)入過來。

完整代碼

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)文章

  • pyinstaller打包程序exe踩過的坑

    pyinstaller打包程序exe踩過的坑

    這篇文章主要介紹了pyinstaller打包exe踩過的坑,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Python標(biāo)準(zhǔn)庫之Sys模塊使用詳解

    Python標(biāo)準(zhǔn)庫之Sys模塊使用詳解

    這篇文章主要介紹了Python標(biāo)準(zhǔn)庫之Sys模塊使用詳解,本文講解了使用sys模塊獲得腳本的參數(shù)、處理模塊、使用sys模塊操作模塊搜索路徑、使用sys模塊查找內(nèi)建模塊、使用sys模塊查找已導(dǎo)入的模塊等使用案例,需要的朋友可以參考下
    2015-05-05
  • 對(duì)python 通過ssh訪問數(shù)據(jù)庫的實(shí)例詳解

    對(duì)python 通過ssh訪問數(shù)據(jù)庫的實(shí)例詳解

    今天小編就為大家分享一篇對(duì)python 通過ssh訪問數(shù)據(jù)庫的實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • Python 中 sorted 如何自定義比較邏輯

    Python 中 sorted 如何自定義比較邏輯

    這篇文章主要介紹了Python中sorted如何自定義比較邏輯,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-02-02
  • Python寫的Socks5協(xié)議代理服務(wù)器

    Python寫的Socks5協(xié)議代理服務(wù)器

    這篇文章主要介紹了Python寫的Socks5協(xié)議代理服務(wù)器,代碼來自網(wǎng)上,需要的朋友可以參考下
    2014-08-08
  • python基于opencv批量生成驗(yàn)證碼的示例

    python基于opencv批量生成驗(yàn)證碼的示例

    這篇文章主要介紹了python基于opencv批量生成驗(yàn)證碼的示例,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-04-04
  • Python3實(shí)現(xiàn)帶附件的定時(shí)發(fā)送郵件功能

    Python3實(shí)現(xiàn)帶附件的定時(shí)發(fā)送郵件功能

    這篇文章主要為大家詳細(xì)介紹了Python3實(shí)現(xiàn)帶附件的定時(shí)發(fā)送郵件功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • python使用Pillow將照片轉(zhuǎn)換為1寸報(bào)名照片的教程分享

    python使用Pillow將照片轉(zhuǎn)換為1寸報(bào)名照片的教程分享

    在現(xiàn)代科技時(shí)代,我們經(jīng)常需要調(diào)整和處理照片以適應(yīng)特定的需求和用途,本文將介紹如何使用wxPython和Pillow庫,通過一個(gè)簡(jiǎn)單的圖形界面程序,將選擇的照片轉(zhuǎn)換為指定尺寸的JPG格式,并保存在桌面上,需要的朋友可以參考下
    2023-09-09
  • Python文件操作類操作實(shí)例詳解

    Python文件操作類操作實(shí)例詳解

    這篇文章主要介紹了Python文件操作類操作實(shí)例代碼,需要的朋友可以參考下
    2014-07-07
  • python如何實(shí)現(xiàn)excel數(shù)據(jù)添加到mongodb

    python如何實(shí)現(xiàn)excel數(shù)據(jù)添加到mongodb

    本文介紹了python是如何實(shí)現(xiàn)excel數(shù)據(jù)添加到mongodb,為了將數(shù)據(jù)導(dǎo)入mongodb,引入了pymongo,xlrd包,需要的朋友可以參考下
    2015-07-07

最新評(píng)論