我们经常在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执行时,会发现并没有执行清屏操作,所以我们需要到命令行运行。最终效果就是我们的字符视频了:
在选取字符表时我们需要注意主体的颜色,如果主体颜色较浅,则字符表的尾部应该为一些复杂字符,如:$%#@&
。字符表头部为一些简单字符,如:-|/
等。如果主体颜色较深,而背景颜色较浅,则反之。当然这没有唯一的标准,大家可以慢慢调节。
总结
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]