分享

python绘制字符画视频的示例代码

 新用户3701XSZY 2021-12-15
目录

·  读取视频

· 转为字符

· 动画

已经11月了,不知道还有没有人看华强买瓜。。。要把华强卖瓜做成字符视频,总共分为三步

· 读取视频

· 把每一帧转为字符画

· 把字符画表现出来

 读取视频

通过imageio读取视频,除了pip install imageio之外,还需要pip install imageio-ffmpeg

由于视频中的图像都是彩色的,故而需要将rgb三色转为单一的强度,并将转化后的图像装入一个列表中。

1

2

3

4

5

6

7

8

9

import imageio

import numpy as np

import matplotlib.pyplot as plt

video = imageio.get_reader('test.mp4')

imgs = []

for img in video:

    imgs.append(np.mean(img,2))

plt.imshow(imgs[0])

plt.show()

 

转为字符

这个视频虽然已被压缩,但对于字符画而言还是太大了,所以转字符画之前需对其进一步压缩。这里采取最简单的方法——即对相邻的像素取平均值。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#将图像宽度缩小至width

from itertools import product   #用于循环嵌套

def resizeImg(img,w,h=None):

    m,n = img.shape

    if n<w:

        return img

    if not h:

        h = int(m*w/n)

    im = np.zeros([h,w])

    rw,rh = n/w,m/h         #缩放比例

    dw,dh = int(rw),int(rh) #取均值的步长

    for i,j in product(range(h),range(w)):

        I,J = int(i*rh),int(j*rw)

        im[i,j] = np.mean(img[I:I+dh,J:J+dw])

    return im

# 测试一下

im = resizeImg(imgs[0],160)

plt.imshow(im)

plt.show()

 

接下来,就可以生成字符画了,所谓字符画,无非是将像素值映射成一个字符,方法非常简单

 

1

2

3

4

5

6

7

8

9

10

11

pixels = "▇圞國图囜ⒶⒷⒸB8&WMZO0QJX@%&jfoavunxr#t/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ^`'. " #用于映射的字符

def im2txt(img):

    im = np.floor(img/255*len(pixels)).astype(int)

    txts = ""

    for line in im:

        txts += "".join([pixels[i] for i in line])

        txts += '\r\n'    #像素换行时文本也要换行

    return txts

#测试

txt = im2txt(im)

print(txt)

结果如下

 

动画

让命令行绘制字符视频,听上去可能有些不可思议,但这个功能可以仅凭python内置的模块实现——即curses,唯一可惜的是,Windows下的Python并不内置这个模块,需要额外安装。

先下载和自己python版本相符的curses,然后通过pip命令安装

1

>pip install "curses-2.2.1+utf8-cp310-cp310-win_amd64.whl"

然后就可以在python中调用了。由于视频太大,所以这里只演示一小段,效果如下

 

主程序的代码如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

if __name__ == "__main__":

    video = imageio.get_reader('test.mp4')

    txts = []

    # 生成字符画

    for img in video:

        im = resizeImg(np.mean(img,2),120,30)

        txts.append(im2txt(im))

    # 初始化屏幕

    scr = curses.initscr()

    scr.timeout(40)     #每次等待键盘输入的时间为40ms

    #scr.

    for txt in cycle(txts):

        scr.addstr(0,0,txt)

        scr.border(0)

        scr.refresh()

        #curses.delay_output(25)

        if scr.getch()==27: #如果按下`esc`则退出`

            break

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多