雪花好看视频_毛线编织雪花毛衣视频

最后更新于: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初学者难题”栏目中的相关文章。

写博客不容易,请支持: