GIF 動画のつくりかた - ControlNet m2m script
詳細
ファイルをダウンロード
モデル説明
ControlNet m2m スクリプトを使用すると、動画のフレームを基に画像を生成し、最後にそれらをまとめてGIF動画として出力してくれます。(動画→動画)
以下の点に注意して読み進めてください。
プロンプトだけで動画を生成することはできません
個人のやり方・一例の紹介にすぎません
必ずしもこの記事の方法に従う必要はありません
この記事の通りにやっても「確実な完成」は保証しません
また、手間に対して得られるのは短い動画1つだけなので、無駄な時間を過ごした気分になることは間違いありません。
タイトルに「ControlNet m2m スクリプト」と銘打っていますが、m2m スクリプト自体は非常にシンプルに使えるものなので、この記事では主にm2mスクリプトを使用する前後で行っている作業の紹介となっています。
私のGIF投稿はこちらから確認できます。
使用ソフトウェア
これらは私が勝手に使っているソフトです。代替となる方法やソフトウェアは世の中に山ほどあるため、自分に合ったものを選択してください。
各ソフトウェアのダウンロード・インストール方法、今回の用途以外での設定や使用方法については本記事では取り上げません。各自で調べてください。
そもそもこれらのソフトウェアについて解説できるだけの深い知識はありませんし、私は人から直接教わったこともありません。ここに書かれているほとんどは調べれば見つかります。
手順
ざっくりとした手順は以下の通りです。
ソース動画を用意する
動画から切り出した画像をControlNetに読み込んでテストする
プロンプトをテストする
Seed値をテストする
ControlNet m2mスクリプトにソース動画を読み込んで出力する
1. ソースとなる動画を用意する
私はOBS Studioを利用して3Dアダルトゲームを録画しました。Blenderから出力したアニメーション動画やMMDの映像なども利用可能です。可逆圧縮用のutvideoコーデックを使用してAVIコンテナに格納しています。
以下はOBS Studioの録画設定です。

すでにソース動画を用意できていればOBS Studioは不要ですが、PC上のアプリケーションを録画する場合は非常に有用なアプリケーションです。基本的にリアルタイム配信用のソフトですが、録画用途としても十分に使えます。
録画が終わったらaviutlで必要な部分だけを切り出します。
あまりにも長い区間を切り出すと出力に膨大な時間がかかるので、短い方が良いです。私は0.5~1秒程度を目安としています。短いと感じる人もいるかもしれませんが、30fpsの動画ならたった1秒でも30枚の画像を生成することになります。
また、ループ再生が連続的に見えるようにカットします。ループ再生に向かない内容なら、開始・終了にフェードイン/アウトのエフェクトなどを使用すると良いでしょう。ただし、この段階ではエフェクトは付けません。
被写体や背景が著しく変化する映像、またはカメラが大きく動くような映像の場合、別シーンとしてカットすることが望ましいです。後でプロンプトを書く際に、映っている内容に合わせて書く必要があるからです。
例えば、被写体が1回転するような映像の場合、正面が映るフレームと後ろが映るフレームが存在します。正面が映るフレームは「breasts」などと書いておけば良いですが、後ろが映るフレームでは「breasts」を削って「back」などと書く必要があります。(「backboob」かもしれませんがw)
カット後、x264エンコーダを使用してmp4形式にエンコードします。aviutlならx264guiExプラグインがあると楽です。
この時、x264のオプションに--qp 0を指定すると可逆圧縮(無劣化)になります。ソース動画にエンコードによるノイズが乗ると、生成される画像に悪影響が出るため、私は可逆圧縮を行っています。
mp4以外の形式のままm2mスクリプトに動画を読み込ませると、自動的にmp4に変換されますが、その際にノイズが乗る可能性があるため、自分でエンコードしています。
2. 動画から切り出した画像をControlNetに読み込んでテストする
動画をいきなりm2mスクリプトに読み込んで、適当なプロンプトやパラメータで出力しても、まず良い動画にはなりません。
まずは動画から画像を切り出し、それをもとにさまざまなプロンプトやパラメータをテストします。
スクリーンショットなど画像を切り出す方法はいくらでもありますが、私はFFMpegの連番出力機能で全フレームを画像化しています。(色々なフレームでテストしたくなることがあるので)
以下はFFMpegで動画から連番画像を出力するコマンド例です。
ffmpeg -hide_banner -i "src.mp4" -ss "0:00" -f "image2" -start_number 1 "%04d.png"
オプションについて説明します。
-ssは画像化を開始する動画時間を指定します。この場合は0:00なので最初のフレームから画像化します。-tオプションで秒数を指定すれば、その分だけ画像化しますが、今回はすべてのフレームを画像化するため指定していません。-fは出力フォーマットを指定します。画像出力の際には書きますが、最後の出力ファイル名に.pngを指定しているため、書かなくても自動で判定されると思われます。-start_numberは連番の開始番号を指定します。0を指定すればゼロベースになります。%04dを出力ファイル名にすると「0埋め4桁」を指定しています。%dとすると0埋めせず、%05dとすれば0埋め5桁になります。
以下はPowerShellでのコマンド実行例です。
このような短いコマンドを1行で打ち込むだけで、瞬時に全フレームを画像化できます。便利ですね。
当たり前ですが、長い動画をすべて画像化すると大量の画像でフォルダが埋もれてしまうため注意が必要です。
動画を扱うにあたり、FFMpegは非常に有用なアプリケーションです。クロップ、リサイズ、フィルター処理、ストリームの分離、エンコードなど、用途は切りません。FFMpegのコマンドだけでさまざまなことが可能です。(先ほど紹介したOBS StudioもFFMpegをラップしています)
FFMpegに限らず、疑問が生じたときはまずネットで検索すべきですが、FFMpegはヘルプも充実しているため、検索と併用して読むと良いでしょう。
以下はヘルプを引く際のコマンド例です。
ffmpeg -hide_banner -h
より詳細なヘルプが必要な場合は以下のようなコマンドがありますが、非常に長い出力になるため、リダイレクトでテキストファイルに出力する例を紹介します。
# long help
ffmepg -hide_banner -h long > longhelp.txt
# full help
ffmpeg -hide_banner -h full > fullhelp.txt
項目を絞ってヘルプを引くこともできます。
ffmpeg -hide_banner -h type=name
このtype=nameの部分を置き換えてコマンドを実行します。
例として、さきほど紹介した画像出力用のimage2で利用できるオプションを検索してみます。
ffmepg -hide_banner -h muxer=image2
この記事を書いている時点では以下のような出力でした。
Muxer image2 [image2 sequence]:
Common extensions: bmp,dpx,exr,jls,jpeg,jpg,jxl,ljpg,pam,pbm,pcx,pfm,pgm,pgmyuv,phm,png,ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,im24,sunras,vbn,xbm,xface,pix,y,avif,qoi.
Default video codec: mjpeg.
image2 muxer AVOptions:
-update <boolean> E.......... continuously overwrite one file (default false)
-start_number <int> E.......... set first number in the sequence (from 0 to INT_MAX) (default 1)
-strftime <boolean> E.......... use strftime for filename (default false)
-frame_pts <boolean> E.......... use current frame pts for filename (default false)
-atomic_writing <boolean> E.......... write files atomically (using temporary files and renames) (default false)
-protocol_opts <dictionary> E.......... specify protocol options for the opened files
-start_number以外にも、連番の開始番号指定に使えるオプションの説明も出力されていますね。
2-1. プロンプトをテストする
さきほど作成したテスト画像を使って、さまざまなプロンプトやControlNetのパラメータで出力を試します。この際はランダムなSeedでテストします。
ControlNetのどのモデルを使うか、パラメータをどのように調整するかは、使用するソース動画によって変わりますが、私はlineartやtileをweight 0.5ずつくらいで使うことが多いです。
新しく実装されたreference_only用の画像を用意すれば、かなりイメージに近づきやすくなると思います。
以下はプロンプトによる違いの例です(ControlNetのモデルとパラメータは同じです)
ソース画像

クオリティにかかわるプロンプトのみ

(masterpiece:1.2, best quality)
Negative prompt: (worst quality, low quality:1.4), EasyNegative
クオリティと描画される(べき)プロンプトを書き込んだもの

thigh sex, clothed female nude male, simple background, black background, sad face young girl, silver short hair, diagonal bangs, blue eyes, green sportswear, covered nipples, panties aside, evil simle ugly man, frottage, grinding, penis, bald, (beard:0.8), (masterpiece:1.2), (best quality)
Negative prompt: (worst quality), (low quality:1.4), EasyNegative, (haze:1.4), (steam:1.4), (breath:1.4), text, subtitled, watermark, (logo:1.4), signature, username, artist name, title, subtitle, date stamp, header, footer, (clothes writing:1.4), tag, name tag, green skin
元の動画があるからといってプロンプトは適当で良いわけではありません。2枚目の画像のように服の色が異なる、男性器が消えるといった大きな違いが生まれます。(太ももコキ動画なのにチンチンが消えるのは流石に耐えがたいですね)
こういった大きな違いが生まれる部分は、プロンプトに書き込んで描くようにします。
元の動画にないものをプロンプトで生成することもできますが、すべてのフレームで安定して同じように描かれるわけではありません。服の色を変える程度であればできますが、模様が出てきたり、色合いが変わったりして安定しません。
また、プロンプトを書いたものの、3枚目の画像ではAIが謎に気を利かせて、見えないはずの女性の右手が描かれてしまいました。このような場合はプロンプトで消すのは難しいため、次のSeed値のテストに進みます。(ガチャ)
2-2. Seed値をテストする
だいたいどのSeed値でも同じような傾向で出力されるようになったら、プロンプトを固定します。
プロンプトを変えずにSeed値を変えて複数の画像を出力し、気に入ったものがあればそのSeed値を固定します。
気に入ったものが一向に出ない場合は、そもそもソース動画とモデルの相性が悪い、プロンプトに過不足がある、細かいことにこだわりすぎているのいずれかです。
以下はさきほど3枚目の画像と同じプロンプトで、Seed値が異なる画像の例です。


この2つのSeed値は服の色が変わり、違いが目立つため採用できませんが、このような大きな違いでなければあまり気にしなくても大丈夫だと思います。
100%完璧で細部まで理想通りの画像を出力することはできません。ある程度の妥協は必要です。
例えば30fpsの動画の1コマはたった0.033…秒しか表示されません。
1コマの出来が良いのが望ましいですが、前後のフレームとの違いが大きい方が最終的に動画として見たときに違和感になると思っています。
この違和感を減らすためにも、Seed値を固定します。
3. ControlNet m2mスクリプトに動画を読み込んで出力する
ControlNetがインストールされていれば、スクリプトの一覧にcontrolnet m2mがあります。
このスクリプトは非常にシンプルで、
スクリプト欄で
controlnet m2mを選択する動画を枠内にドラッグアンドドロップする
Durationを設定する
これだけで使用できます。

ここで1でエンコードして用意したmp4形式のソース動画をm2mスクリプトに読み込みます。
Durationには「1枚のフレームが表示される時間」を指定します(ミリ秒?)
Generateボタンを押して出力を開始すると、各フレームがすべて画像として出力され、全フレームの処理が終わるとGIF動画が完成します。
以上がm2mで動画を出力するまでの基本的な流れです。
その他
エフェクトなどの編集を行いたい場合
m2mスクリプトはGIFを作りますが、同時に連番画像も出力してくれます。
FFMpegを使用すると、それらの連番画像からAVI形式の動画を作成できます。
以下は連番画像をAVI形式に変換するコマンド例です。
ffmpeg -hide_banner -framerate "30" -i "%05d-<SEED_VALUE>.png" -vcodec "utvideo" -pix_fmt "yuv444p" -r "30" "output.avi"
-i "%05d-<SEED_VALUE>.png"の<SEED_VALUE>は、自分の出力に使用したSeed値に置き換えます。山括弧(<と>)は不要です。
-framerate、-rで任意のフレームレートを指定します。
AVI形式に変換すると、動画編集ソフトで自由に編集できます。
編集した動画をGIFにしたい
FFMpegを使用すると(ry)
ffmpeg -hide_banner -i "src.avi" -filter_complex "[0:v] fps=30,scale=512:512,split [a][b];[a] palettegen [p];[b][p] paletteuse=dither=floyd_steinberg" "output.gif"
ディザリングのアルゴリズムは他にもあるので、試してみると良いと思います。見た目やファイルサイズが微妙に変わります。
以下はディザリングアルゴリズムのリストを表示するコマンド例です。
ffmpeg -hide_banner -h filter=paletteuse
投稿やこのページにあった質問への回答
Q. i2iを使っているのか
A. 現状使ったことがないが、フレーム単位で細かい修正が必要ならありかもしれない。ものすごい手間だとは思うが。
Q. 背景を消しているのか
A. 現状消していない。元々シンプルな黒背景の動画をソースにしている。もし背景を消そうと思ったら、高価で高性能なAfter Effectsの「ロトブラシ」のような機能が必要になると思う。それかGIMPで全フレーム(!)の背景を地道に消していくか・・・。
Q. この記事を英訳してほしい
A. 無理。中学英語すら怪しい自分には英訳は不可能。各個人でDeepLやChatGPTなどを使うか、日本語に詳しい人物を探して読んでもらうか。その翻訳内容の正誤も各個人でファクトチェックする必要はあるが……。
そもそも日本語でこのページを書くこと自体に自分に得はないのに、さらに英訳するモチベーションなどない。しかももし英訳したとして、日本語記事を変更したら英訳記事も変更が必要……手間は2倍に。考えるだけもうれしくないですね。
話は逸れるが、EF EPIによると日本人の英語理解度は111か国中80位だったそう。(2022年)
能力レベルとしては「低い」で、アジア圏だけで見ても24か国中14位と低い。
https://www.ef.com/wwen/epi/regions/asia/japan/
https://www.efjapan.co.jp/epi/
大抵の日本人に英語を求めるのは難しいということですね。
「ディスカッション」と言えるほどの建設的な議論はほとんどなされておらず、ChatGPTによるこの記事の雑な英訳(しかも誤っている)が投稿されたため、このページのディスカッション機能は無効にしました。ご理解のほどお願いいたします。
