Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Python生成字符视频

Python生成字符视频

作者头像
ZackSock
发布于 2021-05-18 03:21:06
发布于 2021-05-18 03:21:06
63409
代码可运行
举报
文章被收录于专栏:ZackSockZackSock
运行总次数:9
代码可运行

Python生成字符视频

一、前言

在之前也写过生成字符视频的文章,但是使用的是命令行窗口输出,效果不是很好,而且存在卡顿的情况。于是我打算直接生成一个mp4的字符视频。大致思路和之前一样:Python20行代码实现视频字符化。

下面来看一个效果图:

卡卡西vs带土效果截取

二、OpenCV的操作图像

我们先来看一些基本操作。首先我们需要安装OpenCV,执行下面语句:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install opencv-python

之后就可以使用了。

2.1、读取和显示

我们直接看代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
# 读取图片
img = cv2.imread("1.jpg")
# 显示图片
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()

其中waitKey是等待输入的函数,因为imshow之后显示一瞬间,所以我们需要调用它。而destroyAllWindows是释放窗口。

2.2、灰度转换

灰度转换就是将图片转换成黑白图片(灰色),这样可以方便我们处理像素。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
img = cv2.imread("1.jpg")
# 灰度转换
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

我们还可以直接以灰度形式读入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
# 以灰度形式读入
img = cv2.imread("1.jpg", 0)

2.4、获取图片尺寸并修改尺寸

我们直接看代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
img = cv2.imread("1.jpg", 0)
# 获取图片的高宽
h, w = img.shape
# 缩放图片
res = cv2.resize(img, (w//2, h//2))

因为img的shape属性是一个元组,所以我们可以直接自动拆包。

然后调用cv2.resize函数,第一个参数传入图片,第二个参数传入修改后的尺寸。

2.5、绘制文字

绘制文字我们需要调用cv2.putText函数,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
img = cv2.imread('1.jpg')
# 绘制文字
cv2.putText(
    # 被绘制的图片
    img, 
    # 要绘制的文字
    'Hello',
    # 文字左下角的坐标
    (100, 500),
    # 字体
    cv2.FONT_HERSHEY_SIMPLEX,
    # 字体大小缩放
    20, 
    # 文字颜色
    (0, 0, 0),
    # 文字粗细
    10
)

我们只需要注意这些参数就好了。

2.6、读取视频

读取视频的操作一般是通用的,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
# 读取视频
cap = cv2.VideoCapture('1.mp4')
# 获取视频的帧率
fps = cap.get(cv2.CAP_PROP_FPS)
# 循环读取图片的每一帧
while True:
    # 读取下一帧
    ret, frame = cap.read()
    if not ret:
        break
    else:
        pass
cap.release()

上面我们获取的视频的帧,在写入视频的时候我们需要用到。

2.7、写入视频

写入视频的操作也是常规代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter('11.mp4', fourcc, fps, (w, h))
# 写入视频
writer.write(frame)
***
write.release()

有了这些知识,我们就可以开始下一步工作了。

三、像素映射成字符

对于只有一个通道的图片,我们可以把它当成一个矩形,这个矩形最小单位就是一个像素。而字符化的过程就是用字符替代像素点的过程。所以我们要遍历图像的每个像素点,但是我们应该用什么字符取代呢?

我们颜色有一个参照表,而opencv将这个参数表切割成256份,代表不同的程度,我们也可以做一个参照表,不过表中的内容不是颜色,而是字符。

颜色表

上图为颜色表,我们可以使颜色表和字符表建立映射关系。假如字符表如下:

mqpka89045321@#$%^&*()_=||||}

我们可以得到下列公式:

字符和颜色之间等式

经过变换可以求得相应颜色对应字符表中的字符:

计算字符下标的公式

这个公式不理解也没关系,只需要会用即可。下面就是我们像素转字符的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def pixel2char(pixel):
    char_list = "@#$%&erytuioplkszxcv=+---.     "
    index = int(pixel / 256 * len(char_list))
    return char_list[index]

这个字符表是可以自己定义的。

四、生成字符图片

现在我们只需要将像素逐个转换成字符就好了,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def get_char_img(img, scale=4, font_size=5):
    # 调整图片大小
    h, w = img.shape
    re_im = cv2.resize(img, (w//scale, h//scale))
    # 创建一张图片用来填充字符
    char_img = np.ones((h//scale*font_size, w//scale*font_size), dtype=np.uint8)*255
    font = cv2.FONT_HERSHEY_SIMPLEX
    # 遍历图片像素
    for y in range(0, re_im.shape[0]):
        for x in range(0, re_im.shape[1]):
            char_pixel = pixel2char(re_im[y][x])
            cv2.putText(char_img, char_pixel, (x*font_size, y*font_size), font, 0.5, (0, 0, 0))
    return char_img

这里我们使用了一个np.ones函数,它的作用我们理解为生成一个黑色图片。

生成的尺寸我们先除了scale,然后再乘font_size。scale是原图的缩小程度,因为像素有很多,所以我们需要先把图片缩小。而为了让我们的字体显示更清楚,我们需要把生成的字符图片放大。

因此需要注意,虽然我们生成的图片看起来单调,但是当font_size设置为5时,得到的图片已经比较大了。因此当你生成长时间的视频时,会花费比较多的时间,生成的视频也比较大。

我们来测试一下上面的函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
import numpy as np


def pixel2char(pixel):
    char_list = "@#$%&erytuioplkszxcv=+---.     "
    index = int(pixel / 256 * len(char_list))
    return char_list[index]


def get_char_img(img, scale=4, font_size=5):
    # 调整图片大小
    h, w = img.shape
    re_im = cv2.resize(img, (w//scale, h//scale))
    # 创建一张图片用来填充字符
    char_img = np.ones((h//scale*font_size, w//scale*font_size), dtype=np.uint8)*255
    font = cv2.FONT_HERSHEY_SIMPLEX
    # 遍历图片像素
    for y in range(0, re_im.shape[0]):
        for x in range(0, re_im.shape[1]):
            char_pixel = pixel2char(re_im[y][x])
            cv2.putText(char_img, char_pixel, (x*font_size, y*font_size), font, 0.5, (0, 0, 0))
    return char_img


if __name__ == '__main__':
    img = cv2.imread('dl.jpg', 0)
    res = get_char_img(img)
    cv2.imwrite('d.jpg', res)

效果如下:

生成的字符画

可以看到效果还是很不错的。

五、生成字符视频

有了上面的代码,我们就可以对整个视频进行转换了。将视频转换成字符视频的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def generate(input_video, output_video):
    # 1、读取视频
    cap = cv2.VideoCapture(input_video)

    # 2、获取视频帧率
    fps = cap.get(cv2.CAP_PROP_FPS)

    # 读取第一帧,获取转换成字符后的图片的尺寸
    ret, frame = cap.read()
    char_img = get_char_img(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY), 4)

    # 创建一个VideoWriter,用于保存视频
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    writer = cv2.VideoWriter(output_video, fourcc, fps, (char_img.shape[1], char_img.shape[0]))
    while ret:
        # 读取视频的当前帧,如果没有则跳出循环
        ret, frame = cap.read()
        if not ret:
            break
        # 将当前帧转换成字符图
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        char_img = get_char_img(gray, 4)

        # 转换成BGR模式,便于写入视频
        char_img = cv2.cvtColor(char_img, cv2.COLOR_GRAY2BGR)
        writer.write(char_img)
    writer.release()

下面是卡卡西经典战役的字符视频片段:

卡卡西vs带土效果

完整代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
import numpy as np


def pixel2char(pixel):
    char_list = "@#$%&erytuioplkszxcv=+---.     "
    index = int(pixel / 256 * len(char_list))
    return char_list[index]


def get_char_img(img, scale=4, font_size=5):
    # 调整图片大小
    h, w = img.shape
    re_im = cv2.resize(img, (w//scale, h//scale))
    # 创建一张图片用来填充字符
    char_img = np.ones((h//scale*font_size, w//scale*font_size), dtype=np.uint8)*255
    font = cv2.FONT_HERSHEY_SIMPLEX
    # 遍历图片像素
    for y in range(0, re_im.shape[0]):
        for x in range(0, re_im.shape[1]):
            char_pixel = pixel2char(re_im[y][x])
            cv2.putText(char_img, char_pixel, (x*font_size, y*font_size), font, 0.5, (0, 0, 0))
    return char_img


def generate(input_video, output_video):
    # 1、读取视频
    cap = cv2.VideoCapture(input_video)

    # 2、获取视频帧率
    fps = cap.get(cv2.CAP_PROP_FPS)

    # 读取第一帧,获取转换成字符后的图片的尺寸
    ret, frame = cap.read()
    char_img = get_char_img(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY), 4)

    # 创建一个VideoWriter,用于保存视频
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    writer = cv2.VideoWriter(output_video, fourcc, fps, (char_img.shape[1], char_img.shape[0]))
    while ret:
        # 读取视频的当前帧,如果没有则跳出循环
        ret, frame = cap.read()
        if not ret:
            break
        # 将当前帧转换成字符图
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        char_img = get_char_img(gray, 4)

        # 转换成BGR模式,便于写入视频
        char_img = cv2.cvtColor(char_img, cv2.COLOR_GRAY2BGR)
        writer.write(char_img)
    writer.release()


if __name__ == '__main__':
    generate('in.mp4', 'out.mp4')

我们只需要修改generate的参数就好了。下面是完整的视频效果:

http://mpvideo.qpic.cn/0bf2eiagyaaaouanjonapvqfaiwdnqraa3aa.f10002.mp4?dis_k=5674fd1d24759865d04524585920c021&dis_t=1621308001&spec_id=MzU3MjcxMjI5OA%3D%3D1621308001&vid=wxv_1871555771306426370&format_id=10002

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 新建文件夹X 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
我用字符画出了一个谷爱凌!
之前经常在网上看到那种由一个个字符构成的视频,非常炫酷。一直不懂是怎么做的,这两天研究了一下,发现并不难。
godweiyang
2022/02/23
4150
我用字符画出了一个谷爱凌!
使用Python-去除视频背景
no怕不了木
2023/08/08
8520
使用Python-去除视频背景
OpenCV3计算机视觉——处理文件、摄像头
randomByteArray=bytearray(os.urandom(120))
用户7180691
2020/04/09
7260
AI算法让图片动起来,深情演唱Unravel
项目地址:https://github.com/anandpawara/Real_Time_Image_Animation
mathor
2020/09/15
2.1K0
使用OpenCV调用摄像头,显示图片,获取视频并保存
友情链接:https://blog.csdn.net/u012348774/article/details/78255130
种花家的奋斗兔
2020/11/13
4.4K0
OpenCV 读写视频
下面是完整的代码,里面额外添加了一些边缘检测,求帧差,镜像,添加文字等功能。(上传的动图像素差是腾讯的锅,压缩得太厉害)
用户6021899
2019/08/28
2K0
OpenCV 读写视频
03: 打开摄像头
学习打开摄像头捕获照片、播放本地视频、录制视频等。图片/视频等可到文末引用处下载。
CodecWang
2021/12/07
2.1K0
虽然现在有可以去码的软件了,可视频是如何自动跟踪打码的?
它的身影随处可见,刷脸支付,信息审核,监控搜索等,除了这些常规操作,还可以对视频里的特定人物进行打码。
松鼠爱吃饼干
2020/09/12
6140
虽然现在有可以去码的软件了,可视频是如何自动跟踪打码的?
OpenCV从入门到精通:安装、配置、依赖、基本语法与常用方法详解
本文旨在为计算机视觉初学者提供一份详尽的OpenCV入门指南。从OpenCV的安装配置、依赖项安装,到基本语法和常用方法的解析,我们力求以通俗易懂的方式,配合丰富的代码示例,帮助读者快速掌握OpenCV的核心概念和技术,并为后续深入学习打下坚实的基础。无论您是Python爱好者还是C++开发者,都能从中受益。最后,欢迎大家加我的微信一起交流学习!
默 语
2025/05/12
4530
【深度学习】实例第二部分:OpenCV
执行以下命令安装opencv-python库(核心库)和opencv-contrib-python库(贡献库)。注意:命令拷贝后要合成一行执行,中间不要换行。
杨丝儿
2022/02/28
1.9K0
【深度学习】实例第二部分:OpenCV
虽然现在有可以去码的软件了,可视频是如何自动跟踪打码的?
它的身影随处可见,刷脸支付,信息审核,监控搜索等,除了这些常规操作,还可以对视频里的特定人物进行打码。
松鼠爱吃饼干
2020/09/15
5720
虽然现在有可以去码的软件了,可视频是如何自动跟踪打码的?
新年新气象,100行 Python 代码制作动态鞭炮
当初人们燃竹而爆,是为了驱吓危害人们的山魈。据说山魈最怕火光和响声,所以每到除夕,人们便“燃竹而爆”,把山魈吓跑。这样年复一年,便形成了过年放鞭炮、点红烛、敲锣打鼓欢庆新春的年俗。
用户8544541
2022/01/27
7930
新年新气象,100行 Python 代码制作动态鞭炮
OpenCV 系列教程1 | OpenCV 的 GUI 特性
Matplotlib是一个用于Python的绘图库,它提供了多种绘图方法。在这里,将学习如何使用 Matplotlib 显示图像。可以使用 Matplotlib 放大图片,保存图片等。
机器视觉CV
2019/07/15
3.7K0
OpenCV 系列教程1 | OpenCV 的 GUI 特性
【小技巧】用Python给你的视频添加字幕
在平常调试代码时,需要对视频添加一些文字说明,下面使用 Python 的 OpenCV 和 PIL 对一个视频进行添加文字。
机器视觉CV
2020/07/23
5.1K0
【小技巧】用Python给你的视频添加字幕
基于opencv的摄像头脸部识别抓取及格式储存(python)
刚接触opencv,参照opencv的sample例子做了一个视频头像抓取的小代码,顺便一起学习着用,先上视频抓取及存储代码:
机械视角
2019/10/23
1.1K0
【目标检测】视频输出体积太大?分析视频的编码与码率问题
早期电视台在传输节目信息时,由于带宽有限,于是想在带宽不变的情况下,增加图像的分辨率,让画面看起来更清晰,于是就采用隔行扫描的方式,如下图所示[1],第一帧扫描奇数行的数据,第二帧扫描偶数行的数据,交替进行。由于视觉暂留,在人眼看来就是完整的视频图像。
zstar
2023/12/19
1K0
【目标检测】视频输出体积太大?分析视频的编码与码率问题
python深度学习库系列教程——pyt
和Python一样,当前的OpenCV也有两个大版本,OpenCV2和OpenCV3。相比OpenCV2,OpenCV3提供了更强的功能和更多方便的特性。不过考虑到和深度学习框架的兼容性,以及上手安装的难度,这部分先以2为主进行介绍。
py3study
2020/01/08
1.2K0
opencv︱图片与视频的读入、显示、写出、放缩与基本绘图函数介绍
opencv中读入、显示、写出图片:cv2.imread(), cv2.imshow(), cv2.imwrite()
悟乙己
2019/05/26
5.9K0
有贼出没?看我用python来捉"贼"
最近自己的工位老是丢东西,关键只丢一样东西,而且每天早上来,桌子上都是乱七八糟的。像是遭了贼。
赵云龙龙
2019/11/03
6660
基于Aidlux平台实现ONNX Runtime部署-水果分类-摄像头和视频
连接Aidlux后,使用jupyter notebook --allow-root进行Aidlux平台联系的jupyter notebook安装配置环境:
用户10686717
2023/08/07
3890
推荐阅读
相关推荐
我用字符画出了一个谷爱凌!
更多 >
LV.1
这个人很懒,什么都没有留下~
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验