20行Python代码实现视频字符化功能
作者:ZackSock 发布时间:2023-01-08 21:17:02
我们经常在B站上看到一些字符鬼畜视频,主要就是将一个视频转换成字符的样子展现出来。看起来是非常高端,但是实际实现起来确是非常简单,我们只需要接触opencv模块,就能很快的实现视频字符化。但是在此之前,我们先看看我们实现的效果是怎样的:
上面就是截取的一部分效果图,下面开始进入我们的主题。
一、OpenCV的安装及图片读取
在Python中我们只需要用pip安装即可,我们在控制台执行下列语句:
pip install opencv-python
安装完成就可以开始使用。我们先读取一个图片:
import cv2
im = cv2.imread('jljt')# 读取图片
cv2.imshow('im', im)# 显示图片
cv2.waitKey(0)# 等待键盘输入
cv2.destroyAllWindows()# 销毁内存
首先我们使用cv2.imread
方法读取图片,该方法返回一个ndarray对象。然后调用imshow
方法显示图像,调用后会出现一个窗口,因为这个窗口只会出现一瞬间,所以我们调用waitKey
等待输入,传入0表示无限等待。因为opencv
是使用c++
编写的,所以我们需要销毁内存。
二、OpenCV中的一些基础操作
我们将视频字符化的思路就是先将视频转换为一帧一帧的图像,然后对图像进行字符化处理,最后展示出来就是字符视频的效果了。在我们生成字符画之前,我们还要看一些OpenCV
的操作。
(1)灰度转换
灰度处理是一个非常常用的操作,我们原始的图片是有BGR三个图层(在OpenCV中,图像是以BGR形式读取)。我们进行灰度处理直观上看就是将图片变成黑白,而本质上是将图片的三个图层通过计算,变成一个图层。而这种计算是不需要我们做的,我们只需要调用OpenCV中的函数即可:
import cv2
# 读取图片
im = cv2.imread('jljt.jpg')
# 灰度转换
grey = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
效果图和原图对比如下:
左边为原图,右边为灰度转换后的图像。
(3)改变图片大小
因为字符化后图像会比较大,所以我们需要先缩小图片,我们调用cv2.resize
即可改变图像大小:
import cv2
# 读取图像
im = cv2.imread('jljt.png')
# 改变图像大小
re = cv2.resize(im, (100, 40))
cv2.imshow('11', re)
cv2.waitKey(0)
cv2.destroyAllWindows()
(2)逐帧读取视频
我们可以通过VideoCapture
读取视频,然后调用其中的方法读取每一帧。
import cv2
# 读取视频
video = cv2.VideoCapture('jljt.mp4')
# 读取帧,该方法返回两个参数,第一个为是否还有下一帧,第二个为帧的ndarray对象
ret, frame = video.read()
while ret:
# 循环读取帧
ret, frame = video.read()
有了上面的操作,我们就可以开始我们下一步的工作了。
三、图片字符化
对于只有一个通道的图片,我们可以把它当成一个矩形,这个矩形最小单位就是一个像素。而字符化的过程就是用字符替代像素点的过程。所以我们要遍历图像的每个像素点,但是我们应该用什么字符取代呢?
我们颜色有一个参照表,而opencv将这个参数表切割成256份,代表不同的程度,我们也可以做一个参照表,不过表中的内容不是颜色,而是字符。
上图为颜色表,我们可以使颜色表和字符表建立映射关系。假如字符表如下:
mqpka89045321@#$%^&*()_=||||}
我们可以得到下列公式:
经过变换可以求得相应颜色对应字符表中的字符:
这个公式不理解也没关系,只需要会用即可。下面就是我们完整的代码了:
import cv2
str = 'mqpka89045321@#$%^&*()_=||||}' # 字符表
im = cv2.imread('jljt.jpg')# 读取图像
grey = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)# 灰度转换
grey = cv2.resize(grey, (50, 18))# 缩小图像
str_img = ''# 用于装字符画
for i in grey:# 遍历每个像素
for j in i:
index = int(j / 256 * len(str))# 获取字符坐标
str_img += str[index]# 将字符添加到字符画中
str_img += '\n'
print(str_img)
生成如下字符画:
因为尺寸比较小的关系,看出来的效果不是很好,我们调节好大小就好了。
四、视频转字符
我们知道图片转字符,自然视频转字符就不是什么问题了,我们只需要在逐帧读取中执行图片字符化操作即可。
import os
import cv2
str = 'mqpka89045321@#$%^&*()_=||||}'# 字符表
video = cv2.VideoCapture('jljt.mp4') # 读取视频
ret, frame = video.read()# 读取帧
while ret:# 逐帧读取
str_img = ''# 字符画
grey = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)# 灰度转换
grey = cv2.resize(grey, (100, 40))# 该表大小
for i in grey:# 遍历每个像素点
for j in i:
index = int(j / 256 * len(str))# 获取字符坐标
str_img += str[index]# 将字符添加到字符画中
str_img += '\n'
os.system('cls')# 清除上一帧输出的内容
print(str_img)# 输出字符画
ret, frame = video.read()# 读取下一帧
cv2.waitKey(5)
这样我们就会每个5毫秒执行一帧画面,在我们使用pycharm执行时,会发现并没有执行清屏操作,所以我们需要到命令行运行。最终效果就是我们的字符视频了:
在选取字符表时我们需要注意主体的颜色,如果主体颜色较浅,则字符表的尾部应该为一些复杂字符,如:$%#@&
。字符表头部为一些简单字符,如:-|/
等。如果主体颜色较深,而背景颜色较浅,则反之。当然这没有唯一的标准,大家可以慢慢调节。
来源:https://blog.csdn.net/ZackSock/article/details/105453311


猜你喜欢
- bs4解析原理:1.实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中2.通过调用BeautifulSoup对象中相
- riginal_Data因为程序是为了实现对纯数值型Excel文档进行导入并生成矩阵,因此有必要对第五列文本值进行删除处理。Import_D
- Go语言中rune方法如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希
- 自动化收集SQLSERVER诊断信息相信很多人都遇到过当SQLSERVER出现问题的时候,而你又解决不了需要DBA或者微软售后支持工程师去帮
- 在ACCESS数据库中可以用MSSQL的形式定义操作字符串,也可以采用OLEDB的形式。MSSQL 形式string sqlText = @
- 本文实例为大家分享了微信小程序无滑动效果的tab点击切换的具体代码,供大家参考,具体内容如下<!--pages/dingdan/din
- 题目:给一个列表,找元素在此列表中的位置,如果找到,返回此元素的下标,如果找不到,那就直接返回空解决方法1:# _*_ coding:UTF
- 这是一个通过js实现的支付后的页面,点击支付会跳出一个弹窗,提示你是否要确定支付,确定后进入付后界面,该页面有着10秒倒计时,计时结束后便会
- //实例化上传类$upload = new Zend_File_Transfer();//设置过滤器,大小限制为5M,格式为jpg,gif,
- 农历新年将至,支付宝红包打了一仗,微信在朋友圈屏蔽了它的分享,但单防守还不行,进攻才是最好的防守。昨日,微信支付现金红包接口正式开放,只需开
- 本文实例讲述了Python面向对象之类的定义与继承用法。分享给大家供大家参考,具体如下:定义一个类类中的方法同,类外方法,默认传self值类
- 前言中位数是一个可将数值集合划分为相等的上下两部分的一个数值。如果列表数据的个数是奇数,则列表中间那个数据就是列表数据的中位数;如果列表数据
- 下载地址:https://www.percona.com/downloads/XtraBackup/安装xtrabackup[root@no
- 对于内容驱动的网站,设计好坏的关键是关系型数据库。在这个教程中,我们已经使用了MySQL关系型数据库管理系统(RDBMS)建立了我们的数据库
- 本文实例讲述了PHP递归调用数组值并用其执行指定函数的方法。分享给大家供大家参考。具体分析如下:以下为wordpress原代码,为了偷懒,简
- python开启debug模式的代码如下所示:import requests session = requests.session()imp
- 本文实例讲述了php面象对象数据库操作类。分享给大家供大家参考。具体实现代码如下://此处构造一个数据库操作类,封装所有数据库操作 //可以
- # -*- coding: utf-8 -*-import pymysqlimport xlrd# import codecs#连接数据库c
- 1、使用argparse组件,获取命令行参数;使用re组件,获取需要查找的字符串所在行2、使用pandas组件,对文件进行排序。3、命令行执
- 与Channel区别Channel能够很好的帮助我们控制并发,但是在开发习惯上与显示的表达不太相同,所以在Go语言中可以利用sync包中的W