妖精が跳ねるのを見たことがありますか?pythonで小さな妖精のコードバウンス動画を作ろう
前文
最近、Bサイトで美しい妖精のお姉さんのダンス動画を見て、何度も何度も循環して、長い間離れられなくなりました
フェアリーパープル嬢の弾けるような動画を見ていると、トリプルクリック以外に何ができるんだ?思いついたのは、小さな妖精さんの弾むような動画をコードダンスにできないか?
ダンス動画をコードダンスにして、妖精のお姉さんについて行く方法をお教えします。
動画の出典 [ジーヤン】妖精が跳ねるのを見たことがありますか?[チヤン】(Chijang]
記事の最後に直接スキップする ファン限定特典をゲット
I. コア機能設計
全体としては、次のような手順で完成させる必要があります。
- Bサイトからお嬢様の動画をダウンロードする
- 動画のGIFを撮影し、そのGIFをASCII文字に変換する
- 変換された文字GIFは、各フレームの順番に従って名前を変更し、並べ替えることができます
- ソートされたフレームGIFを画像に変換する
- 文字画像を動画に合成する
- 動画にBGMを追加する
II. 実装手順
1. ビデオのダウンロード
まず用意するのは ユー・ゲットのインストール を使って、動画をダウンロードします。
pip install you-get
<イグ
インストールが完了したら、You-getで動画をローカルにダウンロードします。
Fairy Sister Bounce」動画リンク:https://www.bilibili.com/video/BV124411Q7iV
you-get -o local save path Video link
<イグ
この方法で、ビデオをローカルにダウンロードすることに成功しました。
2. GIFを受信してASCII文字に変換する
次に、ダウンロードした動画を GIFインターセプト この他にも方法があり、pythonを使えば可能です。
GIFは後でASCII文字に変換する必要があるので、傍受するGIFの長さはなるべく長くない方がいいので、ここではXunlei Playerに付属する、一度に20s傍受するGIF傍受ツールを紹介します。
各セグメントを切り出したら、1 2 3の順でGIFに名前を付けます。
ASCII Animatorを使って、インターセプトされた
各フレームごとにGIFからASCIIに変換
. 100ピクセル幅あたりの文字数を設定することで、変換の文字密度を変更することができる。出力形式は、アニメーションASCII(.gif)が選択できます。
ディレクトリファイルの下にtempファイルがあり、これは各gifのフレームごとに変換されたASCII gifが保存されています。以下、これらのASCII gifを処理する必要があり、pythonプロジェクトの下にフォルダをコピーできます。
3. GIFのリネーム
いつものように、最初に後で使用するすべてのライブラリをインポートします。
import os
import re
import shutil
import cv2
from PIL import Image
import moviepy.editor as mpy
無事に変換されたASCII GIFがすべて揃いました。後で画像を動画に統合するために、次は並べ替えを行います。
まず、temp フォルダから読み込んで、すべての gif ファイルから接尾辞が .gif で、それらのgifを後でソートしやすいように命名規則に従ってリネームします。
def rename_gif():
file_list = os.listdir(". /temp") # Read all files from the current folder
# print(file_list)
print("Detected images under folder:")
n = len(file_list)
num_list = []
num1 = num2 = 0
for i in range(n):
s = str(file_list[i])
if s[-4:] == ".gif": # check for suffixes
res = re.findall(r"\d+", s)
if res[0] == '1':
num1 += 1
if res[0] == '2':
num2 += 1
src = os.path.join(os.path.abspath('. /temp/'), s) # original image name
dst = os.path.join(os.path.abspath('. /temp/'), res[0] + '-' + res[1] + '.gif') # rename as you see fit
os.rename(src, dst) # rename, overwriting the original name
num_list.append(num1)
num_list.append(num2)
file_list = os.listdir(". /temp") # Read all files from the current folder
for i in range(n):
s = str(file_list[i])
if s[-4:] == ".gif": # Check the suffix
res = re.findall(r"\d+", s)
src = os.path.join(os.path.abspath('. /temp/'), s) # original image name
a = int(res[0])-1
index = a*num_list[a-1]
dst = os.path.join(os.path.abspath('. /temp/'), str(index + int(res[1])) + '.gif') # rename as you see fit
os.rename(src, dst) # rename, overwriting the original name
gifの名前を変更すると、すべてのgifがフレームごとに順番に表示されるようになりました。後でビデオを構成するときは、名前に従って画像を結合して追加すればいいのです。
4. gifから画像JPGへの変換
次に、フレーム順の gifから画像jpgへ .
def gif2img(gif_path):
gifs = os.listdir(gif_path)
gifs.sort(key=lambda x: int(x[:-4])) # sort by the number of the name string from smallest to largest
for gif in gifs:
im = Image.open(gif_path+gif) # open the gif
im = im.convert('RGB')
if not os.path.exists('. /img'):
os.makedirs('. /img')
for i, frame in enumerate(iter_frames(im)):
frame.save('. /img/' + gif[0:-4] + '.jpg', **frame.info) # save as jpg
5.コンポジットコード・ダンスビデオ
画像合成ビデオ、ここで我々は達成するためにpython-openvcモジュールを使用して、再びあなたが前にそれをインストールしていない場合は、最初にそれをインストールする必要があります。
pip install opencv-python
引数に画像フォルダのパスを渡し、さらにその上に fpsで1秒間に何枚の画像を表示するかを設定します。 .
def charts2video(img_path, video_path):
"""Convert the image in the given directory to a video
Args:
img_path: path to the image
video_path: path and name of the output video
Returns: image to video
"""
images = os.listdir(img_path)
images.sort(key=lambda x: int(x[:-4])) # sort by the number of the name string from smallest to largest
fps = 12 # number of frames
fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', 'V')
im = Image.open(img_path + images[0])
video_writer = cv2.VideoWriter(video_path, fourcc, fps, im.size)
for img_i in images:
frame = cv2.imread(img_path + img_i)
print('Starting to add ' + img_i + ' to the video \n')
video_writer.write(frame) # Note: the image size must be the same as the video size or it won't be added to the video!!!
video_writer.release()
<イグ
6. BGMの追加
コードダンスが完成したら、最後に動画のBGMをコードダンスに追加します。moviepyモジュールを使って、元のビデオからBGMをキャプチャして保存し、最後にコードダンスのビデオに音声を挿入して保存しています。
def add_music():
# read the code video
my_clip = mpy.VideoFileClip('asc.mp4')
# Intercept the background music
audio_background = mpy.AudioFileClip('dance.mp4').subclip(0, 60)
audio_background.write_audiofile('bk.mp3')
# Insert audio into the video
final_clip = my_clip.set_audio(audio_background)
# Save the final video
final_clip.write_videofile('char_video.mp4')
というわけで、妖精のダンス動画からコードダンスが出来上がりました〜。
最終的なコードダンス動画はBサイトにアップしましたので、一緒に楽しんでください。
ドラゴンティーン|テキスト
ソースコードとデータをアップロードしました。記事の最後にある公開番号に従って、[ソースコード]を返信すると、完全なソースコードを入手することができます。
<ブロッククオート過去に発行されたPythonのハイライト。
-
Pythonでピアノの自動演奏スクリプトを一緒に作って、実際に"City in the Sky"を弾いてみました!
エキサイティングなソースコードのバックナンバーは、以下の公開番号から入手できます。
関連
-
AttributeError: 'mywindow' オブジェクトには 'setCentralWidget' という属性がありません。
-
IDLEのサブプロセスが接続されない場合の解決策 - fishcフォーラムより
-
ImportError: 名前 '_validate_lengths' をインポートできない。
-
問題解決しました。Pythonを起動しても「ImportError: No module named site" というエラーでPythonを起動する。
-
ImportError: scipyという名前のモジュールがない(解決済み)
-
pythonフレームワーク Scrapyエラー TypeError: 'float' object is not iterable Solve
-
Pycharmの未解決の参照問題
-
ValueError: 解凍に0以上の値が必要
-
パイソン-ユニコード
-
numpyのconcatenate関数
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
解決済みお客様のCPUは、このTensorFlowバイナリが使用するようにコンパイルされていない命令をサポートしています。AVX AVX2
-
[Django] CSRF 検証に失敗しました。
-
python で word, excel, csv, json ファイルの読み書きをする。
-
Python3 reports AttributeError: '_io.TextIOWrapper' object has no attribute 'open'.
-
AttributeError: モジュール 'time' には属性 'clock' がありません。
-
PyQt5演習:matplotlibでプロットする
-
Python Hashmap/Dictionary 使用ガイド
-
pythonのstring()モジュール
-
TypeError: 'builtin_function_or_method' オブジェクトは反復可能ではありません。
-
TypeError: 'float' オブジェクトが for ループ内で整数として解釈できない どうすればよいですか?