返回顶部
首页 > 资讯 > 后端开发 > Python >用Python字符画出了一个谷爱凌
  • 605
分享到

用Python字符画出了一个谷爱凌

2024-04-02 19:04:59 605人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录怎么实现的?运行方法原理分析完整代码之前经常在网上看到那种由一个个字符构成的视频,非常炫酷。一直不懂是怎么做的,这两天研究了一下,发现并不难。 先来看一个最终效果(如果模糊的话,

之前经常在网上看到那种由一个个字符构成的视频,非常炫酷。一直不懂是怎么做的,这两天研究了一下,发现并不难。

先来看一个最终效果(如果模糊的话,点击下方链接看高清版):

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

怎么实现的?

简单来说,要将一个彩色的视频变成字符画出来的黑白视频,用下面几步就能搞定:

  1. 对原视频进行抽帧,对每一帧黑白化,并将像素点用对应的字符表示。
  2. 将表示出来的字符串再重新组合成字符图像。
  3. 将所有的字符图像再组合成字符视频。
  4. 将原视频的音频导入到新的字符视频中。

运行方法

完整的代码我放在文章末尾了,直接运行python3 video2char.py即可。程序会要求你输入视频的本地路径和转变后的清晰度(0最模糊,1最清晰。当然越清晰,转变越慢)。

运行代码的话需要用到tqdm、OpenCV_python、moviepy等几个库,首先得pip3 install确保它们都有了。

原理分析

这里面最关键的步骤就是如何将一帧彩色图像转变为黑白的字符图像,如下图所示:

从青蛙公主视频抽帧出来的

用字符画出来的

而转变的原理其实很简单。首先因为一个字符画在图像里会占据很大一个像素块,所以必须先对彩色图像进行压缩,连续的一个像素块可以合并,这个压缩过程就是opencv的resize操作。

然后将压缩后的像素点转变为黑白像素点,并转变为对应的字符。字符的话我这里采用的是下面的字符串,从黑到白,经过我的实践这一组是效果最好的:

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

接着就需要将转变后的字符画到新的画布上去,需要注意的点是排布得均匀紧凑了,画布四周最好不要有太多多余的空白。

最后把所有的字符图像合并成视频就行了,但是合并后是没有声音的,需要用moviepy库把原视频的声音导入过来。

完整代码

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("正在将原视频转为字符...")
        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, 直接回车使用默认值0):\n") or 0
    v2char = V2Char(video_path, clarity)
    v2char.gen_video()

以上就是用Python字符画出了一个谷爱凌的详细内容,更多关于Python字符画的资料请关注编程网其它相关文章!

--结束END--

本文标题: 用Python字符画出了一个谷爱凌

本文链接: https://lsjlt.com/news/139374.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 用Python字符画出了一个谷爱凌
    目录怎么实现的运行方法原理分析完整代码之前经常在网上看到那种由一个个字符构成的视频,非常炫酷。一直不懂是怎么做的,这两天研究了一下,发现并不难。 先来看一个最终效果(如果模糊的话,点...
    99+
    2024-04-02
  • 如何使用python画一个爱心
    如何使用python画一个爱心?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。python主要应用领域有哪些1、云计算,典型应用OpenStack。2、WEB前端开发,众多大...
    99+
    2023-06-14
  • 使用Python画一个可爱的冰墩墩
    利用Python绘制可爱的冰墩墩 冰墩墩,作为北京冬奥会的吉祥物,可爱的形象深受广大人们的喜爱。在这篇文章中,我们将使用Python语言来绘制一个可爱的冰墩墩的图像。首先,我们需要了解Python的绘图库matplotlib和n...
    99+
    2024-01-13
    Python绘图 可爱形象设计 冰墩墩绘画
  • java使用字符画一个海绵宝宝
    本文实例为大家分享了java使用字符画一个海绵宝宝的具体代码,供大家参考,具体内容如下 用字符画一个海绵宝宝 用" “和”*"两个字符画出...
    99+
    2024-04-02
  • java如何使用字符画一个海绵宝宝
    今天就跟大家聊聊有关java如何使用字符画一个海绵宝宝,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。用字符画一个海绵宝宝用" “和”*"两个字符画出一个海绵宝宝,...
    99+
    2023-06-26
  • 使用python怎么将一张图片转换为字符画
    这期内容当中小编将会给大家带来有关使用python怎么将一张图片转换为字符画,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。源码(注释很详细):# -*- coding=utf-8&nb...
    99+
    2023-06-06
  • 使用python怎么实现一个驻留字符串
    使用python怎么实现一个驻留字符串?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。python可以做什么Python是一种编程语言,内置了许多有效的工具,Py...
    99+
    2023-06-14
  • 使用python怎么生成一个随机数或随机字符
    这期内容当中小编将会给大家带来有关使用python怎么生成一个随机数或随机字符,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。(1) 生成随机数随机整数import randomnum ...
    99+
    2023-06-14
  • 怎么用Python写一个字符串数字后缀部分的递增函数
    本篇内容介绍了“怎么用Python写一个字符串数字后缀部分的递增函数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!需求:Python处理重名...
    99+
    2023-06-29
  • Python中怎么用replace()一次替换多个不同的字符串
    可以使用字典来一次替换多个不同的字符串,例如: text = "Hello World! This is a test.&...
    99+
    2024-04-02
  • 如何使用Python来进行查询和替换一个文本字符串
    这篇文章主要介绍如何使用Python来进行查询和替换一个文本字符串,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!如何用 Python 来进行查询和替换一个文本字符串?答:可以使用 r...
    99+
    2024-04-02
  • 如何在Python 中使用 join() 函数把列表拼接成一个字符串
    目录1.设置 end=’’2.拼接字符串(string)3.举例内容概要:如何把列表中的元素拼接为一个字符串呢?本文介绍了采用 join() 函数的解决方法。...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作