☞░LaoYuanPythonブログ投稿ディレクトリ:https: //blog.csdn.net/LaoYuanPython░
I.はじめに
数日前、ブロガーは降雪の効果がビデオで達成できるかどうか尋ねました、答えはイエスです。一昨日、古い類人猿は簡単なアイデアを思いつきました。週末にOpenCV-Pythonを使用して、画像ループ表示を介して画像表示に動的な雪片を追加する効果を実現しました。継続的な最適化の後も、効果は良好です。達成するための半日プロセスは要約され、参考のために書かれています。
2.ケースの背景
このスノーフレークは、次の画像(ファイル名:)からのものですf:\pic\snow.jpg
。
背景はどのような写真でもかまいません。以下は、古い類人猿がインターネット上で見つけたエベレスト山(ファイル名:)の画像ですf:\pic\Qomolangma2.jpg
。
エベレストを背景にした空は雪の結晶で覆われていますが、気分はいいですね。
三、アイデアの実現
雪片の落下を実現するには、1枚の画像を1枚表示するだけでは絶対に不十分です。画像をループ状に連続して表示する必要があり、画像を表示するたびに新しい雪片が生成され、既存の位置が表示されます。写真のスノーフレークが更新され、各スノーフレークの位置が正確に管理されます。
自然界では雪片の大きさが異なるため、リアルな効果を出すためには、雪片の大きさをランダムに変化させ、一定の範囲内で回転させる必要もあります。
さまざまなサイズの雪片が絶えず生成されます。雪片が生成されるたびに雪片が変形すると、システムリソースが無駄になります。したがって、処理パフォーマンスを向上させるために、さまざまなサイズと異なる回転角のバッチのみが一度に生成されます。プログラムが初期化されたとき雪片を植える、後続のプログラムが雪片を生成するとき、毎回基本的な雪片画像から変換を開始するのではなく、バッチで生成された雪片の1つを生成する雪片として直接選択します。
第四に、主要な実装コード
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、主な機能
main関数は、背景画像を読み込み、スノーフレーク形状リストを初期化してから、ループして新しいスノーフレークの行を上から生成し、すべてのスノーフレークオブジェクトの位置を動的に調整して背景画像にマージし、200回に1回ループします。 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。その他の指示
プログラムの実行は、メイン関数に直接行うことができます。さらに、このプログラムは、古い類人猿でよく使用されるいくつかの一般的な関数も使用します。関数のこの部分には、readImgFile、addImgToLargeImg、rotationImgが含まれます。その関数については、 「https://blog.csdn.net/LaoYuanPython/article/details/111351901OpenCV-Pythonグラフィックスと画像処理:いくつかの関数の概要と個人使用のためのいくつかのツールの呼び出し構文」を参照してください。関連するコードを自分で実装することは難しくありません。
5、メインプログラムの完全なコードと雪片の落下の影響
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降雪の特殊効果
6、まとめ
この記事では、OpenCV-Pythonを使用して、特定の画像を背景として雪片を作成するための実現アイデア、主要な機能、およびメインプログラムの完全なコードを紹介します。降雪の特殊効果は、実際にはイメージフュージョンの操作に属します。イメージフュージョンの基本的な知識と設計後の実装アイデアを習得している限り、実現は比較的速く、効果は非常に良好です。上記のコードを組み合わせて、雪片のサイズと雪の密度を調整することもできます。
上記のコンテンツの導入により、ビデオとスノーフレークの特殊効果を非常に簡単に実現できます。上記のプロセスで使用した重要な手順をMoviepyのオーディオとビデオの処理と合成に重ね合わせれば、実現できます。老猿はこの記事のコードを少し調整してから、「3行のコードの機能で関連処理が完了しました。Moviepyを勉強した人ならすぐにわかると思います。ここでは紹介しません。しばらくしてから」と書きました。 、古い猿は、Moviepy関連の列に関連する実装を公開します。
上記の実装プロセスに注意してください。
-
スノーフレークの画像は一般的に画像よりも大きいので、適切なサイズに縮小する方法をさらに試す必要があります。以下は、元の画像の半分を省略した後の効果です。
効果があまり良くないことがわかります。 -
左右に移動して落下する雪片の速度と振幅を制御します。速すぎたり、遅すぎたり、大きすぎたり小さすぎたりすることは、雪片が落ちることとは異なります。
画像処理の概要については、「OpenCV-Pythonグラフィックスと画像処理https://blog.csdn.net/laoyuanpython/category_9979286.html」および「https://blog.csdn.net/laoyuanpython/category_10581071」の列を参照してください。 .html OpenCV -Python Beginners Difficult QuestionsCollection "関連記事。
ブログは簡単ではありません、サポートしてください:
この記事を読んで何かを得た場合は、いいね、コメント、ブックマークを付けてください。ご支援ありがとうございます。
古い類人猿についての有料コラム
- 有料のコラム「https://blog.csdn.net/laoyuanpython/category_9607725.htmlPyQtを使用したグラフィカルインターフェイスPythonアプリケーションの開発」では、PythonベースのPyQtグラフィカルインターフェイス開発に関する基本的なチュートリアルを具体的に紹介しています。対応する記事ディレクトリは「https: //blog.csdn .net / LaoYuanPython / article / details / 107580932 PyQtを使用して、グラフィカルインターフェイスPythonアプリケーションの列ディレクトリを開発します";
- 有料のコラム「https://blog.csdn.net/laoyuanpython/category_10232926.htmlmoviepyオーディオおよびビデオ開発コラム」では、moviepyオーディオおよびビデオの編集および合成処理の関連メソッドと、関連を処理するための関連メソッドの使用について詳しく説明しています。記事に対応する編集および合成シーンディレクトリは「https://blog.csdn.net/LaoYuanPython/article/details/107574583moviepyオーディオおよびビデオ開発コラム記事ディレクトリ」です。
- 有料の列「https://blog.csdn.net/laoyuanpython/category_10581071.htmlOpenCV-初心者向けのPythonの難しい質問」は「https://blog.csdn.net/laoyuanpython/category_9979286.htmlOpenCV-Pythonのグラフィックと画像」です。処理「コンパニオンコラム」は、OpenCVの学習で遭遇する問題のいくつかに対する著者の個人的な認識の統合です-Pythonグラフィックスと画像処理。関連情報は基本的に古い猿による繰り返しの研究の結果であり、OpenCVを助けます-Python初心者からより詳細にOpenCVを理解するために、対応する記事ディレクトリは「https://blog.csdn.net/LaoYuanPython/article/details/109713407OpenCV-Python初心者難しい質問コレクションの列ディレクトリ」です。
- 有料のコラム「https://blog.csdn.net/laoyuanpython/category_10762553.htmlPythonCrawlerの概要」では、クローラーの紹介とクロールの基本的な知識を含め、インターネットフロントエンド開発者の観点からクローラー開発のコンテンツを紹介しています。 CSDNの記事情報、記事、コメント、その他の実際のコンテンツなどのブロガー情報を取得します。
最初の2つの列は、特定のPythonの基礎を持っているが、関連する知識がない初心者の読者に適しています。3番目の列は、「https://blog.csdn.net/laoyuanpython/category_9979286.htmlOpenCV-Pythonのグラフィックと画像」を組み合わせてください。処理「使い方を学ぶ。
Pythonの基礎が不足している場合は、Lao Yuanの無料のコラム「https://blog.csdn.net/laoyuanpython/category_9831699.htmlコラム:Pythonの基本的なチュートリアルディレクトリ」からPythonを最初から学ぶことができます。
古い類人猿の読者に興味があり、喜んでサポートする場合は、有料のコラムを購入することを歓迎します。
記事の内容について質問がある場合は、ブログのコメント領域にメッセージを残すか、Laoyuan PythonWeChatパブリックアカウントに従ってメッセージを送信して相談してください。