「Python案例」字符图像,让字符跳动起来!

2022-05-15 18:55:58 浏览数 (1)

欢迎关注本文首发公众号:Python学习实战。公众号主要发布Python相关技术文章,分享Python实用案例、面试问答题、Python基础巩固等内容。

关注【Python学习实战】关注【Python学习实战】

将视频画面全部转为字符,看起来应该比较酷吧...就像下面,输入如下视频:

输入视频输入视频

输出如下视频:

字符动画效果字符动画效果

如果不想看技术细节,可以直接跳到文末获取源码运行。

1 彩色图像转字符图

1.1 基本原理

彩色图转字符图,首先将彩色图转为灰度图,灰度图反映的是图像亮度值。利用亮度值,我们可以将不同的字符替换不同的亮度值。基本原理如下所示。

基本原理基本原理

我们可以提前定义好不同灰度值的对应字符:

代码语言:python代码运行次数:0复制
STRING = "Ñ@#W$9876543210?!abc;: =-,._"

上面字符串从左到右表示亮度越来越亮,当然了,这个字符串不唯一,读者可以根据自己的实际喜好自行设计不同亮度的字符。但有个建议是:

越亮的像素对应的字符应当笔画越少,并且视觉上字符越“空”越好。

对于视频,只需读取每一帧,将每一帧转为字符图,再转回视频即可。

1.2 灰度图转字符图

首先定义一个numpy的二维字符数组,读取每个像素的灰度值,将其转为对应的字符。为了凸显实体,这里将灰度图中越暗区域用越“空”的字符替换,对应的代码实现如下:

代码语言:python代码运行次数:0复制
def gray2ascii(gray):
    h, w = gray.shape[0:2]
    ascii_img = np.zeros((h, w), dtype="<U1")
    idxs = np.round(gray / 255.0 * len(STRING))
    idxs = idxs.astype(np.int32)
    for i in range(h):
        for j in range(w):
            ascii_img[i, j] = STRING[-idxs[i, j]]
    return ascii_img

2 提取视频帧

使用opencvVideoCapture对象读取视频帧,每次提取完视频帧后通过callback函数回调。

代码语言:python代码运行次数:0复制
def extract_frames(video_path, callback):
    video = cv2.VideoCapture(video_path)
    num_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) 
    for _ in tqdm(range(num_frames)):
        _, frame = video.read()
        if frame is not None:
            callback(frame)
        else:
            break

3 帧转视频

每一帧图像经过转换为字符图像后,接下来是写入到视频中,代码如下:

代码语言:python代码运行次数:0复制
WRITER = None 
def write_frame(frame, out_path, fps=30):
    global WRITER
    if WRITER is None:
        size = frame.shape[0:2][::-1]
        WRITER = cv2.VideoWriter(
            out_path,
            cv2.VideoWriter_fourcc(*'mp4v'),  # 编码器
            fps,
            size)
    WRITER.write(frame)

4 源码获取

  1. 关注我的公众号:Python学习实战
  2. 后台回复:字符图。获取完整的字符图转换源码。

如果您觉得本文有帮助,辛苦您点个不需花钱的赞,您的举手之劳将对我提供了无限的写作动力! 也欢迎关注我的公众号:Python学习实战, 第一时间获取最新文章。

关注【Python学习实战】关注【Python学习实战】

0 人点赞