雪花好看视频_毛线编织雪花毛衣视频
最后更新于:2022-02-10 12:18:26
☞ ░ 老猿 Python 博文目录:░
一、简介
前几天有博主问视频里能不能实现飘雪的效果,答案是肯定的。老猿前天简单想了一下,用OpenCV-Python循环显示图片,达到了给图片显示添加动态雪花的效果。经过不断的优化,效果还是不错的。花了半天时间才实现 过程总结写下来,供大家参考。
二、案例背景
这片雪花来自以下图片(文件名:f:\pic\snow.jpg):
背景可以是任何图片。以下是网上找到的珠穆朗玛峰图片(文件名:f:\pic\Qomolangma2.jpg):
珠穆朗玛峰背景的天空飘着雪花,心情不错吧?
三、实施思路
要实现雪花飘落,单张图片的单次展示肯定是不够的雪花好看视频,还需要循环展示图片雪花好看视频,而且每展示一张图片,都会生成一个新的雪花,以及已有的雪花在图片中的位置图片已更新。每个雪花的位置都被精确管理。
自然界中雪花的大小是不一样的,所以为了提高逼真效果,还需要让雪花的大小在一定范围内随机变化和旋转。
不断产生不同大小的雪花。如果每次生成雪花时都对雪花进行变换,是对系统资源的浪费。因此,为了提高处理性能,只有在程序开始初始化时才会产生各种大小和不同旋转角度的批次。种植雪花,后续程序生成雪花时,直接将批量生成的雪花中的一个作为要生成的雪花,而不是每次都从基础雪花图像进行变换。
四、关键实现代码4.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)
4.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
4.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.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
4.5、其他说明
程序的执行可以直接用main函数来完成。此外,这个程序还用到了一些老猿经常使用的常用功能。这些函数包括 readImgFile、addImgToLargeImg 和 rotationImg。根据《工具函数函数及调用语法介绍》的介绍,大家自己实现相关代码并不难。
五、主程序完整代码及下雪效果5.1、主程序完整代码
# -*- coding: utf-8 -*-
import cv2,random
import numpy as np
from opencvPublic import addImgToLargeImg,readImgFile,rotationImg
snowShapesList = [] #雪花形状列表
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()
5.2、下雪效果
六、总结
本文介绍了通过OpenCV-Python以特定图像为背景制作雪花飘落效果的主程序的实现思路、关键功能和完整代码。雪花效应其实属于图像融合的操作。只要掌握了图像融合的基本知识和设计后的实现思路,实现起来还是比较快的,效果也相当不错。结合上面的代码,还可以调整雪花的大小和雪的密度。
有了以上内容的介绍,给视频添加雪花效果就很容易了。可以通过将上述流程中用到的关键步骤与Moviepy音视频处理合成叠加起来来实现。老猿稍微调整了这篇文章的代码,然后写了一个三行代码的功能就完成了相关的处理。相信学过Moviepy的人可以很快实现。我不会在这里介绍它。过段时间,老猿会在Moviepy相关专栏中公布相关实现。
上述实现过程需要注意:
雪花图片一般比图片想要的效果要大。如何将尺寸缩小到合适的尺寸需要更多尝试。下面是把原图缩小一半后的效果。
可以看出,效果不是很理想。
控制雪花左右移动和下落的速度和幅度。太快、太慢、幅度太大或太小都不像飘落的雪花。
更多关于图像处理的介绍,请参考“OpenCV-Python图形与图像处理”和“OpenCV-Python初学者难题”栏目中的相关文章。
写博客不容易,请支持:
发表回复