05 Python Numpy moivepy 生成MP4 爱满一颗心

118 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。 Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言, 随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。 Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。 Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器码。

七夕就要来了,不论你是不是一个人,都祝你七夕快乐!!!!

前提:

下载moviepy,说实话我下载有点久

pip install moviepy

在运行前切记切记:

运行完在文件夹中会看到生成的结果fullheart.mp4  的文件,切记不要在pycharm中点开,不然你后面再到文件夹中打开这个文件就受损了

代码:

import urllib.request
import numpy as np
from scipy.ndimage.filters import convolve
import moviepy.editor as mpy

# 下载心形脉络图和文字
filename = ("https://live.staticflickr.com/65535/51375413098_6835046704_o.png")
urllib.request.urlretrieve(filename, "fullheart.png")
filename = ("https://live.staticflickr.com/65535/51376189625_5ce9caa671_o.png")
urllib.request.urlretrieve(filename, "fullwords.png")

"""
* @Author: xiaofang
* @Description: 
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:732481539
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
"""

#### 参数和约束条件
infection_rate = 0.4
incubation_rate = 0.1

dispersion_rates = [0, 0.07, 0.03]  # for S, I, R

# 该内核会模拟病毒如何用一个位置扩散至邻近位置
dispersion_kernel = np.array([[0.5, 1, 0.5],
                              [1, -6, 1],
                              [0.5, 1, 0.5]])

heart = mpy.ImageClip("fullheart.png").resize(width=400)
words = mpy.ImageClip("fullwords.png").resize(width=400)  # 后面在渲染的时候直接把文字矩阵与心形图矩阵相加
SIR = np.zeros((3, heart.h, heart.w), dtype=float)
SIR[0] = heart.get_frame(0).mean(axis=2) / 255
WORDS = words.get_frame(0)

start = int(0.4 * heart.h), int(0.611 * heart.w)  # 在这里修改最开始感染的位置
SIR[1, start[0], start[1]] = 0.8  # infection in Grenoble at t=0

dt = 1.0  # 一次更新=实时1个小时
hours_per_second = 7 * 24  # one second in the video = one week in the model
world = {'SIR': SIR, 't': 0}


##### 建模

def infection(SIR, infection_rate, incubation_rate):
    """ Computes the evolution of #Sane, #Infected, #Rampaging"""
    S, I, R = SIR
    newly_infected = infection_rate * R * S
    newly_rampaging = incubation_rate * I
    dS = - newly_infected
    dI = newly_infected - newly_rampaging
    dR = newly_rampaging
    return np.array([dS, dI, dR])


def dispersion(SIR, dispersion_kernel, dispersion_rates):
    """ Computes the dispersion (spread) of people """
    return np.array([convolve(e, dispersion_kernel, cval=0) * r
                     for (e, r) in zip(SIR, dispersion_rates)])


def update(world):
    """ spread the epidemic for one time step """
    infect = infection(world['SIR'], infection_rate, incubation_rate)
    disperse = dispersion(world['SIR'], dispersion_kernel, dispersion_rates)
    world['SIR'] += dt * (infect + disperse)
    world['t'] += dt


# 用MoviePy制作动画

def world_to_npimage(world):
    """ Converts the world's map into a RGB image for the final video."""
    coefs = np.array([2, 25, 25]).reshape((3, 1, 1))
    accentuated_world = 255 * coefs * world['SIR']
    image = accentuated_world[::-1].swapaxes(0, 2).swapaxes(0, 1)
    return np.minimum(255, image) + WORDS  # 加上文字


def make_frame(t):
    """ Return the frame for time t """
    while world['t'] < hours_per_second * t:
        update(world)
    return world_to_npimage(world)


animation = mpy.VideoClip(make_frame, duration=16)
# 可以将结果写为视频或GIF(速度较慢),每次选择一个格式渲染
# animation.write_gif('fullheart.gif', fps=30)
animation.write_videofile('fullheart.mp4', fps=30)