来源:https://blog.csdn.net/LaoYuanPython/article/details/115298737

首先看一下目标效果:

素材准备 & 思路分析

本次雪花来源于如下图片(文件名:f:\pic\snow.jpg):

背景可以是任意图片,下面是老猿在网上找到的一张珠峰图像(文件名:f:\pic\Qomolangma2.jpg):

珠峰背景的天空飘落着纷纷扬扬的雪花,意境不错吧?

实现思路

要实现雪花飘落,单张图片的单次显示肯定不够,需要不停循环显示图片,并且在每次图片显示时,生成新的雪花并更新图片中已有雪花的位置,这就需要将图片中每个雪花的位置精确管理。

自然界的雪花大小是不同的,因此为了提升逼真效果,还需要使得雪花大小在一定范围内随机变化和旋转。

不停产生大小不同的雪花,如果每次产生雪花都对雪花进行变换其实浪费了系统的资源,因此为了提升处理性能,只在程序开始初始化时一次批量生产各种不同大小、不同旋转角度的各种雪花,后续程序生成雪花时,直接从批量生成的雪花中取一个作为要生成的雪花,而不用每次从基本的雪花图像开始进行变换。

关键实现代码

1、生成各种雪花形状

def initSnowShapes():    """    从文件中读入雪花图片,并进行不同尺度的缩小和不同角度的旋转从而生成不同的雪花形状,这些雪花形状保存到全局列表中snowShapesList    """    global snowShapesList    imgSnow = readImgFile(r'f:\pic\snow.jpg')     imgSnow = cv2.resize(imgSnow, None, fx=0.2, fy=0.2) #图片文件中的雪花比较大,需要缩小才能象自然的雪花形象    minFactor,maxFactor = 50,100  #雪花大小在imgSnow的0.5-1倍之间变化
    for factor in range(minFactor,maxFactor,5): #每次增加5%大小        f = factor*0.01        imgSnowSize = cv2.resize(imgSnow, None, fx=f, fy=f)        for ange in range(0,360,5):#雪花0-360之间旋转            imgRotate = rotationImg(imgSnowSize,ange)            snowShapesList.append(imgRotate)

2、产生一排雪花​​​​​​​

def generateOneRowSnows(width,count):    """    产生一排雪花对象,每个雪花随机从snowShapesList取一个、横坐标位置随机、纵坐标初始为0    :param width: 背景图像宽度    :param count: 希望的雪花数    :return:一个包含产生的多个雪花对象信息的列表,每个列表的元素代表一个雪花对象,雪花对象包含三个信息,在snowShapesList的索引号、初始x坐标、初始y坐标(才生成固定为0)    """    global snowShapesList    line = []    picCount = len(snowShapesList)     for loop in range(count):        imgId = random.randint(0,picCount-1)        xPos = random.randint(0,width-1)        line.append((imgId,xPos,0))    return line

3、将所有雪花对象融合到背景图像​​​​​​​

def putSnowObjectToImg(img):    """    将所有snowObjects中的雪花对象融合放到图像img中,融合时y坐标随机下移一定高度,x坐标左右随机小范围内移动    """    global snowShapesList,snowObjects    horizontalMaxDistance,verticalMaxDistance = 5,20 #水平方向左右漂移最大值和竖直方向下落最大值    snowObjectCount = len(snowObjects)    rows,cols = img.shape[0:2]    imgResult = np.array(img)    for index in range(snowObjectCount-1,-1,-1):        imgObj = snowObjects[index] #每个元素为(imgId,x,y)        if imgObj[2]>rows: #如果雪花的起始纵坐标已经超出背景图像的高度(即到达背景图像底部),则该雪花对象需进行失效处理            del(snowObjects[index])        else:            imgSnow = snowShapesList[imgObj[0]]            x,y = imgObj[1:] #取该雪花上次的位置            x = x+random.randint(-1*horizontalMaxDistance,horizontalMaxDistance) #横坐标随机左右移动一定范围            y = y+random.randint(1,verticalMaxDistance) #纵坐标随机下落一定范围            snowObjects[index] = (imgObj[0],x,y) #更新雪花对象信息            imgResult = addImgToLargeImg(imgSnow,imgResult,(x,y),180) #将所有雪花对象图像按照其位置融合到背景图像中    return imgResult #返回融合图像

4、主函数

主函数读入背景图片,初始化雪花形状列表,然后循环自顶部产生一排新的雪花,并将所有雪花对象动态调整位置后融合到背景图像,每200毫秒循环一次,直至按ESC退出。

​​​​​​​

def main():    global snowShapesList,snowObjects    bg = readImgFile(r'f:\pic\Qomolangma2.jpg')    initSnowShapes()    rows,cols = bg.shape[:2]    maxObjsPerRow = int(cols/100)
    while(True):        snowObjects += generateOneRowSnows(cols,random.randint(0,maxObjsPerRow))        result = putSnowObjectToImg(bg)        cv2.imshow('result',result)        ch = cv2.waitKey(200)        if ch==27:break

主程序完整代码及雪花飘落效果

5.1、 主程序完整代码​​​​​​​

# -*- coding: utf-8 -*-import cv2,randomimport numpy as np
from opencvPublic import addImgToLargeImg,readImgFile,rotationImgsnowShapesList = [] #雪花形状列表snowObjects=[]  #图片中要显示的所有雪花对象def initSnowShapes():    """    从文件中读入雪花图片,并进行不同尺度的缩小和不同角度的旋转从而生成不同的雪花形状,这些雪花形状保存到全局列表中snowShapesList    """    global snowShapesList    imgSnow = readImgFile(r'f:\pic\snow.jpg')    imgSnow = cv2.resize(imgSnow, None, fx=0.2, fy=0.2) #图片文件中的雪花比较大,需要缩小才能象自然的雪花形象    minFactor,maxFactor = 50,100  #雪花大小在imgSnow的0.5-1倍之间变化
    for factor in range(minFactor,maxFactor,5): #每次增加5%大小        f = factor*0.01        imgSnowSize = cv2.resize(imgSnow, None, fx=f, fy=f)        for ange in range(0,360,5):#雪花0-360之间旋转,每次旋转角度增加5°            imgRotate = rotationImg(imgSnowSize,ange)            snowShapesList.append(imgRotate)
def generateOneRowSnows(width,count):    """    产生一排雪花对象,每个雪花随机从snowShapesList取一个、横坐标位置随机、纵坐标初始为0    :param width: 背景图像宽度    :param count: 希望的雪花数    :y:当前行对应的竖直坐标    :return:一个包含产生的多个雪花对象信息的列表,每个列表的元素代表一个雪花对象,雪花对象包含三个信息,在snowShapesList的索引号、初始x坐标、初始y坐标(才生成固定为0)    """    global snowShapesList    line = []    picCount = len(snowShapesList)    for loop in range(count):        imgId = random.randint(0,picCount-1)        xPos = random.randint(0,width-1)        line.append((imgId,xPos,0))    return line
def putSnowObjectToImg(img):    """    将所有snowObjects中的雪花对象融合放到图像img中,融合时y坐标随机下移一定高度,x坐标左右随机小范围内移动    """    global snowShapesList,snowObjects    horizontalMaxDistance,verticalMaxDistance = 5,20 #水平方向左右漂移最大值和竖直方向下落最大值    snowObjectCount = len(snowObjects)    rows,cols = img.shape[0:2]    imgResult = np.array(img)    for index in range(snowObjectCount-1,-1,-1):        imgObj = snowObjects[index] #每个元素为(imgId,x,y)        if imgObj[2]>rows: #如果雪花的起始纵坐标已经超出背景图像的高度(即到达背景图像底部),则该雪花对象需进行失效处理            del(snowObjects[index])        else:            imgSnow = snowShapesList[imgObj[0]]            x,y = imgObj[1:] #取该雪花上次的位置            x = x+random.randint(-1*horizontalMaxDistance,horizontalMaxDistance) #横坐标随机左右移动一定范围            y = y+random.randint(1,verticalMaxDistance) #纵坐标随机下落一定范围            snowObjects[index] = (imgObj[0],x,y) #更新雪花对象信息            imgResult = addImgToLargeImg(imgSnow,imgResult,(x,y),180) #将所有雪花对象图像按照其位置融合到背景图像中    return imgResult #返回融合图像def main():    global snowShapesList,snowObjects
    initSnowShapes()    bg = readImgFile(r'f:\pic\Qomolangma2.jpg')    rows,cols = bg.shape[:2]    maxObjsPerRow = int(cols/100)
    while(True):        snowObjects += generateOneRowSnows(cols,random.randint(0,maxObjsPerRow))        result = putSnowObjectToImg(bg)        cv2.imshow('result',result)        ch = cv2.waitKey(200)        if ch==27:break
main()

总结

本文介绍了通过OpenCV-Python以特定图像为背景制作雪花飘落特效的实现思路、关键函数功能以及主程序的完整代码。雪花飘落特效实际上属于图像融合的操作,只要掌握图像融合的基础知识以及设计后实现思路,实现起来还是比较快的,效果也挺不错。结合上面代码,大家还可以调整雪花的大小以及飘雪的密集程度。

以上实现过程需要注意:

1、雪花图片一般会比图片需要的效果大,怎么缩小到合适的大小需要多试一下,下面是才开始将原始图片只缩写一半之后的效果。

可以看到该效果就不太让人满意。

2、控制好雪花左右移动以及下落的速度和幅度,太快、太慢以及幅度过大或过小都不太象在雪花飘落。

OpenCV-Python 雪花飘落特效相关推荐

  1. OpenCV-Python图形图像处理:制作雪花飘落特效

    ☞ ░ 老猿Python博文目录:https://blog.csdn.net/LaoYuanPython ░ 一.引言 前几天有博友咨询,能否在视频中实现雪花飘落的效果,答案是肯定的.老猿前天简单构思 ...

  2. 【打造寒冬中的浪漫雪景——OpenCV-Python 雪花飘落特效】

    [打造寒冬中的浪漫雪景--OpenCV-Python 雪花飘落特效] 寒冬到来,想要为自己的网站或者APP增添一些浪漫雪景效果吗?那就别错过这篇OpenCV-Python实现雪花飘落特效的教程!本教程 ...

  3. JS实现逼真的雪花飘落特效

    逼真的雪花飘落特效 效果图: 图片素材 : --> ParticleSmoke.png 代码如下,复制即可使用: <!doctype html> <html> <h ...

  4. 雪花飘落代码java_JS实现的雪花飘落特效示例

    本文实例讲述了JS实现的雪花飘落特效.分享给大家供大家参考,具体如下: 首先我们要创建一个HTML文件,将其命名为index.html Canvas - 雪花特效 *{ margin:0px; pad ...

  5. HTML5的canvas雪花飘落特效

    HTML5的canvas雪花飘落特效 一.html代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&qu ...

  6. 用JavaScript实现网页雪花飘落特效

    不知道大家有没有看到过别人的网页有雪花飘落的特效,我当时看到真的觉得好好看,于是乎就去借鉴别人做的特效代码,最终将这个特效成功放到自己做的网页上啦~代码放到下面啦,可以自己设置颜色,雪花形状的大小,雪 ...

  7. 5种Python雪花飘落代码(建议收藏)

    前言 本文章向大家介绍用 Python 实现雪花飘落效果,运行以下代码,你将会看到一个美丽的雪花效果.你可以根据自己的需求,调整代码中的参数值以及其他细节. 第一种 普通雪花代码: import tu ...

  8. vue实现雪花飘落特效

    <p>可以使用 HTML5 canvas 元素来实现雪花飘落的动画效果.你可以在 canvas 中绘制雪花的图形,然后使用 JavaScript 实现动画效果.</p> < ...

  9. HTML好看的时钟倒计时源码+雪花飘落特效

    正文: 此源码页为单html纯代码,新年倒计时,背景雪花飘落效果,倒计时时间日期在JS/app.js文件第21行代码自行修改即可. 程序: wwueg.lanzoub.com/iR4KG07zpizg ...

最新文章

  1. 数学知识--Unconstrained Optimization(第一章)
  2. spring_Spring Boot登录选项快速指南
  3. Java的浅拷贝与深拷贝总结
  4. c语言一个整数各位数字个数_C语言实现把字符串中的数字转换成整数
  5. Python 爬虫原理实现自动google翻译
  6. 龙果学院mysql分布式集群代码_龙果学院-MySQL大型分布式集群解决方案
  7. OWASP-ZAP扫描器的使用(攻击)
  8. 华三服务器linux系统安装u盘,华三H3CR4900服务器安装linux系统
  9. 范型编程系列二(非原创)
  10. 计算机主机英语怎么说,电脑的英文-电脑的主机这个词英语怎么说?电脑的主 – 手机爱问...
  11. prescan学习笔记1
  12. “红黑树”,我一脸懵逼......
  13. 一元二次方程的解c语言,一元二次方程求解程序完整代码
  14. 如何判断车与路边线距离_靠边停车如何判断车轮与马路牙子的距离?一个办法真的很简单...
  15. 【六类网线的制作方法】
  16. 5.JVM三大性能调优参数:-Xms -Xmx -Xss
  17. HTML标签和说明属性
  18. 华为鸿蒙生态班怎么上,华为联合西北工业大学开设“鸿蒙生态菁英班”: 50 人左右...
  19. java web分层和层间数据传递 vo bo po (转载)
  20. java vbs_一键定位配置JAVA SDK 环境变量 VBS脚本全自动操作正式开源

热门文章

  1. VC6如何使用VS2005中的CImage类功能
  2. Cannot open precompiled header file:'Debug/password.pch' No such file or directory
  3. 用C语言实现Ping程序功能
  4. mysql超时失效c3p0_解决c3p0和MySQL集成情况下,连接长时间闲置后重新使用时报错的问题...
  5. mysql根据叶子找父亲_MySQL:如何在特定节点中查找叶子
  6. mysql 5.6 emoji_让MySQL支持Emoji表情 mysql 5.6
  7. python3多进程 pool manager_python多进程multiprocessing Pool相关问题
  8. java字符串逐个分解_改进JAVA字符串分解的方法
  9. 叛逆的仔:不听老板的话,还要用行动给老板来个响亮耳光!
  10. 又一个 Java 面试神器!