OpenCV-Python 雪花飘落特效

ShellCollector 2021-04-06 23:27:18
Python OpenCV 雪花 飘落 opencv-python


来源: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、控制好雪花左右移动以及下落的速度和幅度,太快、太慢以及幅度过大或过小都不太象在雪花飘落。

版权声明
本文为[ShellCollector]所创,转载请带上原文链接,感谢
https://blog.csdn.net/jacke121/article/details/115471222

  1. Spark Delta Lake 0.4.0 发布,支持 Python API 和部分 SQL
  2. How to transfer office files to PDF
  3. Are you still worried about multiple excel summary statistics? Python second processing really fragrant!
  4. Making music aggregate downloader with Python
  5. Spark delta Lake 0.4.0 is released, supporting Python API and part of SQL
  6. Python信息搜集
  7. Python information gathering
  8. Python - 关于类(self/cls) 以及 多进程通讯的思考
  9. Python - thinking about class (self / CLS) and multi process communication
  10. Python - 关于类(self/cls) 以及 多进程通讯的思考
  11. Python - thinking about class (self / CLS) and multi process communication
  12. Python信用评分卡建模(附代码)
  13. Python credit score card modeling (with code)
  14. 学Python需要学数据库吗?Python学习教程!
  15. Do you need to learn database to learn Python!
  16. Python私有变量如何定义?Python学习教程!
  17. How to define Python private variables? Python tutorial!
  18. Python数据分析入门(六):Pandas的函数应用
  19. Introduction to Python data analysis (6): function application of pandas
  20. 学Python需要学数据库吗?Python学习教程!
  21. Do you need to learn database to learn Python!
  22. Python描述 LeetCode 80. 删除有序数组中的重复项 II
  23. C++/python描述 AcWing 94. 递归实现排列型枚举
  24. C++/python描述 AcWing 92. 递归实现指数型枚举
  25. Python描述 LeetCode 88. 合并两个有序数组
  26. 苏州大学计算机考研 复试机试真题2013-2021真题及Python题解
  27. Python描述 LeetCode 781. 森林中的兔子
  28. 字典和json的区别是什么?Python学习
  29. Python describes leetcode 80. Removing duplicate items from ordered arrays II
  30. C + + / Python description acwing 94. Recursive implementation of permutation enumeration
  31. C + + / Python description acwing 92. Recursive implementation of exponential enumeration
  32. Python describes leetcode 88. Merging two ordered arrays
  33. Real computer test questions 2013-2021 of computer postgraduate entrance examination of Soochow University and python solutions
  34. The rabbit in the forest
  35. Python中的魔法属性
  36. What's the difference between dictionary and JSON? Python learning
  37. Magic properties in Python
  38. 字典和json的区别是什么?Python学习
  39. What's the difference between dictionary and JSON? Python learning
  40. python刷题-字母图形
  41. Python brush questions - letter graphics
  42. Python数据分析入门(七):Pandas层级索引
  43. Introduction to Python data analysis (7): Pandas hierarchical index
  44. Python 操作腾讯云短信(sms)详细教程
  45. Python operation Tencent cloud SMS (SMS) detailed tutorial
  46. Python数据可视化,完整版实操指南 !
  47. Python data visualization, full version of the practical guide!
  48. 上手Pandas,带你玩转数据(2)-- 使用pandas从多种文件中读取数据
  49. 上手Pandas,带你玩转数据(1)-- 实例详解pandas数据结构
  50. Using pandas to read data from various files
  51. Hands on pandas, take you to play with data (1) -- detailed explanation of pandas data structure with examples
  52. Pandas数据结构基础用法
  53. Basic usage of pandas data structure
  54. Python读取ini配置文件,保存到对象属性
  55. Python reads the INI configuration file and saves it to the object properties
  56. Foundation of Python: classes in Python
  57. python刷题-闰年判断
  58. python刷题-01字串
  59. How to judge leap year
  60. Python brush title-01 string