效果展示
首先看一下目標(biāo)效果:
素材準(zhǔn)備 & 思路分析
本次雪花來源于如下圖片
背景可以是任意圖片,下面是老猿在網(wǎng)上找到的一張珠峰圖像
珠峰背景的天空飄落著紛紛揚(yáng)揚(yáng)的雪花,意境不錯(cuò)吧?
實(shí)現(xiàn)思路
要實(shí)現(xiàn)雪花飄落,單張圖片的單次顯示肯定不夠,需要不停循環(huán)顯示圖片,并且在每次圖片顯示時(shí),生成新的雪花并更新圖片中已有雪花的位置,這就需要將圖片中每個(gè)雪花的位置精確管理。
自然界的雪花大小是不同的,因此為了提升逼真效果,還需要使得雪花大小在一定范圍內(nèi)隨機(jī)變化和旋轉(zhuǎn)。
不停產(chǎn)生大小不同的雪花,如果每次產(chǎn)生雪花都對(duì)雪花進(jìn)行變換其實(shí)浪費(fèi)了系統(tǒng)的資源,因此為了提升處理性能,只在程序開始初始化時(shí)一次批量生產(chǎn)各種不同大小、不同旋轉(zhuǎn)角度的各種雪花,后續(xù)程序生成雪花時(shí),直接從批量生成的雪花中取一個(gè)作為要生成的雪花,而不用每次從基本的雪花圖像開始進(jìn)行變換。
關(guān)鍵實(shí)現(xiàn)代碼
1、生成各種雪花形狀
def initSnowShapes(): “”“ 從文件中讀入雪花圖片,并進(jìn)行不同尺度的縮小和不同角度的旋轉(zhuǎn)從而生成不同的雪花形狀,這些雪花形狀保存到全局列表中snowShapesList ”“” global snowShapesList imgSnow = readImgFile(r‘f:picsnow.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之間旋轉(zhuǎn) imgRotate = rotationImg(imgSnowSize,ange) snowShapesList.append(imgRotate)
2、產(chǎn)生一排雪花
def generateOneRowSnows(width,count): “”“ 產(chǎn)生一排雪花對(duì)象,每個(gè)雪花隨機(jī)從snowShapesList取一個(gè)、橫坐標(biāo)位置隨機(jī)、縱坐標(biāo)初始為0 :param width: 背景圖像寬度 :param count: 希望的雪花數(shù) 一個(gè)包含產(chǎn)生的多個(gè)雪花對(duì)象信息的列表,每個(gè)列表的元素代表一個(gè)雪花對(duì)象,雪花對(duì)象包含三個(gè)信息,在snowShapesList的索引號(hào)、初始x坐標(biāo)、初始y坐標(biāo)(才生成固定為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、將所有雪花對(duì)象融合到背景圖像
def putSnowObjectToImg(img): “”“ 將所有snowObjects中的雪花對(duì)象融合放到圖像img中,融合時(shí)y坐標(biāo)隨機(jī)下移一定高度,x坐標(biāo)左右隨機(jī)小范圍內(nèi)移動(dòng) ”“” 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] #每個(gè)元素為(imgId,x,y) if imgObj[2]》rows: #如果雪花的起始縱坐標(biāo)已經(jīng)超出背景圖像的高度(即到達(dá)背景圖像底部),則該雪花對(duì)象需進(jìn)行失效處理 del(snowObjects[index]) else: imgSnow = snowShapesList[imgObj[0]] x,y = imgObj[1:] #取該雪花上次的位置 x = x+random.randint(-1*horizontalMaxDistance,horizontalMaxDistance) #橫坐標(biāo)隨機(jī)左右移動(dòng)一定范圍 y = y+random.randint(1,verticalMaxDistance) #縱坐標(biāo)隨機(jī)下落一定范圍 snowObjects[index] = (imgObj[0],x,y) #更新雪花對(duì)象信息 imgResult = addImgToLargeImg(imgSnow,imgResult,(x,y),180) #將所有雪花對(duì)象圖像按照其位置融合到背景圖像中 return imgResult #返回融合圖像
4、主函數(shù)
主函數(shù)讀入背景圖片,初始化雪花形狀列表,然后循環(huán)自頂部產(chǎn)生一排新的雪花,并將所有雪花對(duì)象動(dòng)態(tài)調(diào)整位置后融合到背景圖像,每200毫秒循環(huán)一次,直至按ESC退出。
def main(): global snowShapesList,snowObjects bg = readImgFile(r‘f:picQomolangma2.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=[] #圖片中要顯示的所有雪花對(duì)象
def initSnowShapes(): “”“ 從文件中讀入雪花圖片,并進(jìn)行不同尺度的縮小和不同角度的旋轉(zhuǎn)從而生成不同的雪花形狀,這些雪花形狀保存到全局列表中snowShapesList ”“” global snowShapesList imgSnow = readImgFile(r‘f:picsnow.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之間旋轉(zhuǎn),每次旋轉(zhuǎn)角度增加5° imgRotate = rotationImg(imgSnowSize,ange) snowShapesList.append(imgRotate)
def generateOneRowSnows(width,count): “”“ 產(chǎn)生一排雪花對(duì)象,每個(gè)雪花隨機(jī)從snowShapesList取一個(gè)、橫坐標(biāo)位置隨機(jī)、縱坐標(biāo)初始為0 :param width: 背景圖像寬度 :param count: 希望的雪花數(shù) 當(dāng)前行對(duì)應(yīng)的豎直坐標(biāo) 一個(gè)包含產(chǎn)生的多個(gè)雪花對(duì)象信息的列表,每個(gè)列表的元素代表一個(gè)雪花對(duì)象,雪花對(duì)象包含三個(gè)信息,在snowShapesList的索引號(hào)、初始x坐標(biāo)、初始y坐標(biāo)(才生成固定為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中的雪花對(duì)象融合放到圖像img中,融合時(shí)y坐標(biāo)隨機(jī)下移一定高度,x坐標(biāo)左右隨機(jī)小范圍內(nèi)移動(dòng) ”“” 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] #每個(gè)元素為(imgId,x,y) if imgObj[2]》rows: #如果雪花的起始縱坐標(biāo)已經(jīng)超出背景圖像的高度(即到達(dá)背景圖像底部),則該雪花對(duì)象需進(jìn)行失效處理 del(snowObjects[index]) else: imgSnow = snowShapesList[imgObj[0]] x,y = imgObj[1:] #取該雪花上次的位置 x = x+random.randint(-1*horizontalMaxDistance,horizontalMaxDistance) #橫坐標(biāo)隨機(jī)左右移動(dòng)一定范圍 y = y+random.randint(1,verticalMaxDistance) #縱坐標(biāo)隨機(jī)下落一定范圍 snowObjects[index] = (imgObj[0],x,y) #更新雪花對(duì)象信息 imgResult = addImgToLargeImg(imgSnow,imgResult,(x,y),180) #將所有雪花對(duì)象圖像按照其位置融合到背景圖像中 return imgResult #返回融合圖像
def main(): global snowShapesList,snowObjects
initSnowShapes() bg = readImgFile(r‘f:picQomolangma2.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()
總結(jié)
本文介紹了通過OpenCV-Python以特定圖像為背景制作雪花飄落特效的實(shí)現(xiàn)思路、關(guān)鍵函數(shù)功能以及主程序的完整代碼。雪花飄落特效實(shí)際上屬于圖像融合的操作,只要掌握?qǐng)D像融合的基礎(chǔ)知識(shí)以及設(shè)計(jì)后實(shí)現(xiàn)思路,實(shí)現(xiàn)起來還是比較快的,效果也挺不錯(cuò)。結(jié)合上面代碼,大家還可以調(diào)整雪花的大小以及飄雪的密集程度。
以上實(shí)現(xiàn)過程需要注意:
1、雪花圖片一般會(huì)比圖片需要的效果大,怎么縮小到合適的大小需要多試一下,下面是才開始將原始圖片只縮寫一半之后的效果。
可以看到該效果就不太讓人滿意。
2、控制好雪花左右移動(dòng)以及下落的速度和幅度,太快、太慢以及幅度過大或過小都不太象在雪花飄落。
編輯:lyn
-
OpenCV
+關(guān)注
關(guān)注
29文章
625瀏覽量
41218 -
python
+關(guān)注
關(guān)注
55文章
4774瀏覽量
84386
原文標(biāo)題:OpenCV-Python圖形圖像處理:制作雪花飄落特效
文章出處:【微信號(hào):vision263com,微信公眾號(hào):新機(jī)器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論