前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DIY 雪花特效(一)

DIY 雪花特效(一)

作者头像
用户6021899
发布2020-03-23 15:06:09
1.3K0
发布2020-03-23 15:06:09
举报
文章被收录于专栏:Python编程 pyqt matplotlib

对任意一张图片,我们可以用代码给它加点雪花特效,做成动图。

原图:

加特效后:

首先我们需要雪花的图片,比如下面这张(其实这张有点不太真实,不过无妨,我只是拿它来做演示)。

做图像分割后我们就得到了16张雪花的图片(其实一张也足够):

用pickle模块将它们保存到本地,以供后续调用。

万事俱备,下面我们来给原图加上雪花。主要代码如下:

代码语言:javascript
复制
"""
Created on Sat Dec 15 10:15:18 2019
@author: wangsp
"""
import numpy as np
from matplotlib import pyplot as plt
import cv2
import pickle
import imageio
from random import randint,normalvariate

def create_gif(frames, gif_name,duration=0.3,reverse=False):
    if reverse: frames.sort(reverse=True)
    imageio.mimsave(gif_name,frames,"GIF",duration=duration)
    return frames
    
BG = plt.imread("plum.jpg")#加载背景图
H,W,C = BG.shape
frame  = BG.astype(np.uint16)
frames = []

class Snow:
    def __init__(self,type_,x0,y0,speed0,scale):
        self.scale = scale
        #type_ : from 1 to 16
        self.data = self.get_snow(type_)
        self.x = x0
        self.y = y0
        self.speed = speed0
        
    def get_snow(self, type_):
        with open("snow%d.data"%type_,"rb") as f:
            data = pickle.load(f)
            #缩小一点
            self.h,self.w = data.shape
            data = cv2.resize(data,(int(self.h*self.scale),int(self.w*self.scale)))
            
            self.h,self.w = data.shape
            snow = np.zeros((self.h,self.w,3),dtype = np.uint8)
            snow[data==1] = np.array([255,255,255])
        return snow
        
    def update(self): #动画效果
        global frames, frame
        
        c = self.w%2 #compensation, 偶数0, 奇数1
        #restore
        if self.y < self.h:
            frame[0:self.y, self.x-int(self.w/2):self.x+int(self.w/2)+c] = BG[0:self.y,self.x-int(self.w/2):self.x+int(self.w/2)+c]
        elif self.y < H:
            frame[self.y-self.h:self.y, self.x-int(self.w/2):self.x+int(self.w/2)+c]= BG[self.y-self.h:self.y,self.x-int(self.w/2):self.x+int(self.w/2)+c]
        elif self.y < H + self.h:
            frame[self.y-self.h:, self.x-int(self.w/2):self.x+int(self.w/2)+c] = BG[self.y-self.h:,self.x-int(self.w/2):self.x+int(self.w/2)+c]
        else:
            pass
        
        self.x += 0
        self.y += self.speed
        if self.y < self.h:
            frame[0:self.y, self.x-int(self.w/2):self.x+int(self.w/2)+c] += self.data[self.h-self.y:,:]
        elif self.y < H:
            frame[self.y-self.h:self.y, self.x-int(self.w/2):self.x+int(self.w/2)+c] += self.data
        elif self.y < H + self.h:
            frame[self.y-self.h:, self.x-int(self.w/2):self.x+int(self.w/2)+c] += self.data[:H-(self.y-self.h),:]
        else:
            self.y = 0
        frame[frame>255] = 255
       

n_snows = randint(100,120) # include both ends
snows  = []
for i in range(n_snows):
    type_ = randint(1,16) #include both ends
    x0 = randint(10,W-10)
    y0 = randint(0,H)
    speed = int(normalvariate(3,0.5))
    scale = normalvariate(0.02,0.005)
    snow = Snow(type_,x0, y0, speed,scale)
    snows.append(snow)
              
n_frames = 30 #因为公众号只能穿5M以下的图,所以帧数弄少一点
for n in range(n_frames):
    for i in range(n_snows):
        snows[i].update()
    frames.append(frame.astype(np.uint8))
                
create_gif(frames,"snow_plum_5M.gif",0.01) #创建GIF

至此 ,我们可以给小倩下场雪:

效果略显粗糙,有时间的话会再做优化。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python可视化编程机器学习OpenCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档