ControlNet OpenPoseで人物のポーズを指定する―4つの実例で使い方と効果を確認 ~ 画像生成AI実験メモ ⑤

画像生成AIを楽しむ中で、歯がゆい思いをすることのひとつに、「こういうポーズの画像を生成したい」と思っても、その通りにならないこと、というのがあります。
本記事に掲載している人物画像は、すべて生成AIにより作成したものであり、特定の実在人物をモデルにしたものではありません。
プロンプトの難しさ
例えば「手を挙げる」動作。
こんなプロンプトとパラメータ設定で試してみましょうか。LoRAは前回のテーマで作成したものを使用します。
Prompt
<lora:ai_model_v6-000060:0.8>ai_model_v6,
one Japanese woman in her 20s or early 30s,
raising one hand,
natural smile, casual clothes,
standing,
upper body, front view, looking at the camera,
simple outdoor background, realistic photo
Negative prompt
multiple people, extra arms, extra hands, missing fingers,
deformed hands, malformed limbs,
cropped arms, text, illustration, anime
・Model:v1-5-pruned-emaonly
・Sampler:DPM++ 2M
・Schedule type:Karras
・Sampring steps:24
・CFG Scale:7
・Seed:-1
・サイズ(Width x Height):768 x 432
これで生成されたのが、こんなのです。

とか、

とか。
「raising one hand」、つまりは「片手を上げる」とプロンプトを書いて12枚を生成しても、
・片手を上げた画像:5枚
・手を上げなかった画像:7枚
という結果です。ただ、これは良い方だったようで、他に12枚をセットで出したら、手を上げたのが1枚だけ、ということもありました。
LoRAを使用しているのが良くないのかも、ということで、LoRAなしでも生成してみたんですが、
・片手を上げた画像:3枚
・両手を上げた画像:3枚
・手を上げなかった画像:6枚
という結果に。片手の3枚のうち、1枚は胸のあたりに握りこぶしを持ってきた画像なので、手を上げている、というのには微妙なものです。
なので、LoRAを使用すると多少学習画像に引っ張られる傾向は見られるようですが、極端に悪くも無さそうなので使用する前提で話を進めたいと思います。なんせ、架空のアシスタントキャラクターですからね。サンプル画像として登場して頂かないと。
ところで、「片手を上げる」って、どういうイメージを持たれました?
私は、遠くにいる人にも見えるように大きく手を振っているような姿をイメージしてました。
なので、プロンプトをちょっと変更。
Prompt
<lora:ai_model_v6-000060:0.8>ai_model_v6,
one Japanese woman in her 20s or early 30s,
waving one hand high in the air so that someone far away can notice her, big wave,
natural smile, casual clothes,
standing, upper body, front view,
looking at the camera, simple outdoor background, realistic photo
こんな画像が出来ました。一番意に添ったのがこの一枚ですかね。

ごてごて書いたのが奏功したのか、
・片手を上げた画像:11枚
・手を上げなかった画像:1枚
となっています。が、他の人に気付いてもらえるくらいに手を上げていたのは5枚だけで、他のは、ちょっと手を上にしている、という程度のものでした。
やっぱり、プロンプトだけで意図したポーズの画像を生成するのは難しいですね。
OpnePoseを使ってみる
そんなときに役に立つ(だろう…と思ってる)のが、ControlNet の OpenPose です。
ControlNetは、参考画像の構図や輪郭、ポーズなどを画像生成に反映させるための機能で、OpenPoseは、その中でも人物の関節位置を骨格データとして読み取り、指定したポーズに近い人物を生成するために使うものとなります。
OpenPoseの導入
Stable Diffusion Web UI(AUTOMATIC1111版、以下A1111)の txt2img タブで、Generationにある「ControlNet」を展開します。
ControlNetが無い場合は、拡張機能のインストールから必要となります。既に導入済みなら、この項は読み飛ばしてください。
インストール時の画面イメージなどは、この記事を参照にしてください。
Adetailerのときと同じように、上部メニューから次の順に開きます。
1.Extentions
2.Install from URL
3.「URL for extension’s git repositroy」に
https://github.com/Mikubill/sd-webui-controlnet.git を入力
4. Install をクリック
5. インストール完了後に、Installedタブを開く

6. Apply and restart UI をクリック
これで、ControlNetが表示されればOKなんですが、表示されない場合、下記の対応が必要になる可能性があります。
コマンドプロンプトでこのような表示が出るケースです。
AttributeError: module 'mediapipe' has no attribute 'solutions'
いったん、A1111を終了して、コマンドプロンプトから、stable-diffusion-webui のフォルダで、下記コマンドを実行します。
venv\Scripts\python.exe -m pip show mediapipe
これで、
Name: mediapipe
Version: 0.10.35
このように、0.10.30以降のバージョンが表示された場合、Python 3.10環境で実績のある0.10.21を明示して入れ直すのが良いそうです。
なので、一旦アンインストールして、インストール。
venv\Scripts\python.exe -m pip uninstall -y mediapipe
venv\Scripts\python.exe -m pip install --no-deps mediapipe==0.10.21
念のため、確認します。
venv\Scripts\python.exe -c "import mediapipe as mp; print(mp.__version__); print(hasattr(mp, 'solutions'))"
これで、 0.10.21 と出れば OKです。
…なんですが、ちょっといろいろやらかしてしまったので、これが最短の解決策かどうかはわからなくなりました。すみませんが、これへの対応に関しては、自己責任でお願いします。。
次に、OpenPose用ControlNetモデル(control_v11p_sd15_openpose.pth)をダウンロードする必要があります。今回は、SD1.5の場合についての説明となります。
例によって、Hugging Face を使用しますので、以下のリポジトリを参照してください。
https://huggingface.co/lllyasviel/ControlNet-v1-1
「Files and Versions」タブにあるファイル一覧から、control_v11p_sd15_openpose.pthを選び、Downloadアイコン(↓)を押します。
ダウンロードしたファイルを下記のフォルダに格納します。
stable-diffusion-webui
└─ extensions
└─ sd-webui-controlnet
└─ models
└─ control_v11p_sd15_openpose.pth
A1111のtxt2imgで、Generationにある「ControlNet」を展開すると、Model選択の欄が見えますが、何も選択できない状態のはずです。上記でファイルをフォルダに格納した直後なら、右側の回転するリフレッシュアイコンをクリックします。
Modelの選択肢に、control_v11p_sd15_openposeが現れれば、ひとまずはOKです。
両手を延ばした伸び
では、次に、OpenPose用の参考画像を探しましょう。
先ほどの例とはちょっと違うのですが、両手を上に伸ばして、背伸びをしている様子がすがすがしそうでいいかな、と。
手元にそのような写真があればいいんですが、なければネット上から探します。
例えば、Pexels とか。
Pexelsで公開されている画像は、作品制作の視覚的な参考資料として利用することが認められています。今回は画像そのものを作品に使用するのではなく、OpenPoseで人物の骨格情報を抽出し、ポーズ指定の資料として利用します。
検索ワードは日本語での自然文も受け付けられるようですね。なので「腕を伸ばして伸びをする女性」なんてワードで検索してみます。
たくさんの画像が出てきますので、ある意味、生成画像なみに面白いのですが、今回の趣旨とは違いますね(笑)
このような画像をダウンロードしてみました。

A1111のtxt2imgで、Generationにある「ControlNet」を展開します。
画面中ほどにある「Enable」にチェックを付け、「ここに画像をドロップ」に、ダウンロードした画像をドロップします。
Preprocessorには、標準の openpose_full でもいいんですが、より精細に取得できるらしい dw_openpose_full を選びました。
Modelは、SD1.5なら、表示されている control_sd15_openposeで大丈夫です。
そのあたりを設定した後、PreprocessorとModelの間にあるアイコン「Run preprocessor」をクリックします。
すると、しばらくして、画像から抽出された骨格データが表示されます。
いい感じで反映されてそうですね。
※正確に伝えると、骨格データには左側に、薄く写る二人目の骨格データが出ていました。それをEditで編集し削除しています。
骨格の取得が出来たら、いよいよ生成です。
パラメータの設定をします。
Control Weight:1
Starting Control Step:0
Ending Control Step:1
Control Mode:Balanced
Resize Mode:Resize and Fill
つまりは、変更したのは「Resize Mode」だけですね。
メインの設定は、
・Model:v1-5-pruned-emaonly
・Sampler:DPM++ 2M
・Schedule type:Karras
・Sampring steps:28
・CFG Scale:6.5
・Seed:-1
・サイズ(Width x Height):768 x 432
Prompt
<lora:ai_model_v6-000060:0.8>ai_model_v6,
1 young Japanese woman, standing in a sunny summer highland,
stretching comfortably with both arms straight up, slight back bend,
face turned slightly upward, eyes gently closed, soft smile,
refreshing morning air, blue sky, white clouds, green meadow,
natural outdoor light, realistic photo, thigh-up shot
Negative prompt
multiple people, extra arms, extra hands, extra fingers, missing fingers,
malformed hands, bad anatomy, deformed body, twisted arms,
poorly drawn hands, poorly drawn face, long neck, duplicate,
out of frame, cropped hands, blurry, low quality, lowres
としてみました。
OpenPoseで骨格の指定はするものの、プロンプトにはその背景というのか、設定した状況を記載しておくのが良さそうです。
比較の意味で、先に「OpenPose」の「Enable」をOFFにした状態、つまりは機能を切った状態で12枚生成してみると、「with both arms straight up」としているにも関わらず、両手を上げた画像は1枚もありませんでした。片手が上がっていたのが2枚だけです。
では、いよいよ、EnableをONにして、12枚を生成。
待つことしばし。
一番良かったのがこれですかね。

身体の向き、手の上げ方等は、骨格モデルの通りです。
ちなみに、12枚をSeed(-1)で作成していますので、他の画像を含めて一覧で出してみると、この通り。

骨格モデルが上半身だけなので、下半身を推測で作ってしまっているものもありますが、概ね「ポーズとしては」期待通りです。
いかんせん、「顔が…」です。※OpenPoseの問題では無いため、あえて小さめの(顔の表情がはっきりとわからない)画像だけにしています。
これは、ADetailerによる補正が必要そうですね。
というわけで、ADetailerを用いて、前回同様の設定で顔を補正しています。以下、すべての生成画像で適用しています。

やっぱり、指が絡み合うのはOpenPoseでも非常に難しい、ということが判りました。(絡み合ってるわけではないんですが、指の関節がすぐそばに集まるのはかなり苦手なようです)
このポーズとしての最後、Hires.fixも活用して、1280×720の画像を生成しました。

「心地よい良い伸び」感は、意図したほど出なかったですが、プロンプトだけでは、かなりのボツ画像の発生が想像されますので、OpenPoseの果たす役割は大きいのかな、と思います。
両手を後ろに
続いては、両手を後ろに回しての伸びというか、ストレッチ風のもの。
こんな感じですね。
ここで注目してもらいたいのが、右手が写っていないこと。骨格モデルでも、右肩から先は表現されていません。
プロンプトには、「両手を後ろに」としています。
Prompt
<lora:ai_model_v6-000060:0.8>ai_model_v6,
1 young Japanese woman in a summer highland meadow,
standing with both hands on her lower back, arching backward, chest open,
head tilted back, looking upward, gentle smile,
blue sky, green grass, natural light, realistic photo
Negative prompt
extra arms, extra hands, malformed hands, twisted body,
bad anatomy, cropped head, blurry
これがベストショットになるでしょうか。(顔は、通常の前向きではないので、ADetailerのInpaint denoising strengthを強めにしています)

…が。
右手は垂らした状態になってますよね。

右手(手首から先)が見えないのは12枚中1枚のみ。
骨格モデルで指示が出来ていないものは、生成AIによる補完となる、ということですね。
モデル画像から抽出された関節位置をもとに人物の姿勢を作り出します。良くも悪くも、モデル画像で隠れていた部分は、「生成されない(見えない)」という情報にはならずに、情報が不足しているので生成時に補うべき存在となってしまうんですね。
ですので、完全にモデル画像のポーズを生成したければ、もっとプロンプトで補ってあげる必要がありそうですね。とはいえ、まぁまぁいい感じの画像になったので、これくらいにしておきます。
でも、一覧の画像に、一枚、変なのがありますよね。

これ、身体が「向こう側」を向いています。

そうなんです。OpenPoseは、ラベルとしては「右手」「左手」など左右を意識したものになっているんですが、生成画像側でそのままの意味として守られるわけではない、ということなんです。
この左右の色分けが生成時に保証されるものではない、ということ。
なので、このように左右反転(前後反転)も生じてしまいます。このあたりは、プロンプトで補うしかない、ということになります。
もっとも、これまでの例でお判りの通り、プロンプトの解釈も絶対ではないですので、難しいところです。今回のは顔の向き情報が曖昧なので、さらに間違いを誘発しやすかった、ということなんだと思います。
ベンチに座る
両手をベンチについて座っている、という画像をイメージしています。
モデル画像をPexelsで探してみたんですが、どうもしっくりと来るものが見つからないんですね。
じゃぁどうするか、ということで、「無ければ作ってしまえ」と、SDXLでいくつか作成してみました。なんか、本末転倒のような気がしなくも無いですが、これも、安定したポーズのためです。
モデル画像生成のため、LoRAやADetailerは使用せず、シンプルに768×768の画像での生成です。
Prompt
1 young Japanese woman, sitting on a park bench,
both palms pressed on the bench seat beside her hips,
leaning back slightly, supporting herself with both arms,
three-quarter view, relaxed expression, realistic photo
Negative prompt
multiple people, extra arms, extra hands, malformed hands,
bad anatomy, twisted body, standing, blurry, lowres, cropped hands
画風がアニメ寄りであろうが、顔が崩れようが(SDXLなので、ほぼ顔崩れはありませんでしたが)、その辺は気にしません。
その中で気に入ったのがこちら。

ちょっとベンチとの向きが不自然ですが、両手をベンチについて座る感じが気に入りました。
これを、OpenPoseで取り込みます。
今回、3パターン目にして、足先まで入ったのは初めてですね。
2例目と違って、右手が描かれているのがちょっと不思議な感じはしますが、全体的な骨格モデルとしては理想通りのものになりました。
Prompt
<lora:ai_model_v6-000060:1>ai_model_v6,
1 young Japanese woman, sitting on a park bench,
both hands placed on the bench beside her hips for support,
leaning slightly back, looking slightly upward, relaxed expression, gentle smile,
summer highland meadow, blue sky, green grass, natural light, realistic photo
Negative prompt
multiple people, standing, extra arms, extra hands, malformed hands,
bad anatomy, twisted body, floating hands, disconnected arms, blurry, lowres
これで12枚を生成してみます。この生成では、SD1.5のベースモデルに戻しています。もちろん、ADetailerも有効に戻しています。顔の描画サイズが小さいので、無効のままだと全て顔の崩壊を起こしてましたからね。

ベンチと腰の位置が浮いた感じになるのが出てくるんじゃないかと不安があったんですが、12枚ともにきちんと座ってますね。

元画像よりも顔の傾きが正面寄りなのは、LoRAの影響でしょうね。
…と書いていて、プロンプトの設定が <lora:ai_model_v6-000060:1> だったことに気付きました。重みが1です。これまでの2例は、0.8にしてました。
というわけで、0.8にすると、こうなりました(全てではないですけどね)。

改めて、LoRAの重みって、生成を左右することを思い知りましたね。
こちらも、Hires.fixを使用して 1280×720の画像を生成してみました。その中のベストがこちらです。

スカートで足元は見えませんが、クロスしている雰囲気は出ています。顔も斜め向きですしね。
ちなみに、2例目とは違って、脚がこちら側に延びているので、背面向きの画像は一切ありませんでした。そのあたりはきちんと考えられているようですね。
今回の例では、参考に出来る画像が無い場合、作ってみる、というのも有効だということが分かったケースとなりました。
しゃがんで花を愛でる
最後に、花畑でしゃがんで花々を楽しむ様子を生成してみたいと思います。
Pexelsで探すんですが、「しゃがんで花を見る女性」よりも「woman crouching looking at flowers」とした方が、期待する画像の割合が高いような気がします。英語の方がヒットしやすいのかもしれません。
で、生成された骨格モデルは、ちょっと微妙なものになりました。

左手が宙に浮いた状態になってるんですね。これがどう影響するか、特に修正せずに画像生成してみたいと思います。
Prompt
<lora:ai_model_v6-000060:0.8>ai_model_v6,
1 young Japanese woman, crouching in a summer meadow, looking at small wildflowers,
one hand resting near her knee, the other hand reaching gently toward the flowers,
slightly leaning forward, relaxed expression, gentle smile,
blue sky, green grass, natural outdoor light, realistic photo, full body
Negative prompt
multiple people, standing, extra arms, extra hands, extra legs, malformed hands,
bad anatomy, twisted body, fused legs, disconnected limbs, blurry, lowres, cropped body
プロンプトで、右手の描画を少し誘導しています。

手のあたりが込み入ったポーズになるので難しくなることを想定していただけに、意外と「見れる画像(違和感の無い画像)」が多い気がします。
骨格モデルの右手がつながっていないので、それが影響してか腕の位置がおかしなものもありますが、さすがはOpenPoseですね、全体のポーズを大きく外すものがありません。
OpenPoseを使用せずに、プロンプトだけで生成しようとすると、12枚生成してこのようになりました。

プロンプトだけでは、しゃがむという姿勢を表現することすら難しいので、大量に生成した画像から、しゃがんでいる画像を選び出し、その中からベストなものを選定する、となると、何枚のボツ画像が出てくるか、恐ろしくなります。
というわけで、4例目のベストは、この1枚としました。

左手の位置が骨格モデルとは違うんですが、それもまたよし、ということで。
今回、4つのポーズを出力して、いかにOpenPoseが有効かということが判りました。プロンプトだけで苦労する(無駄な画像を大量に出力する)よりも、ちょっとの手間で、意図したポーズの画像が生成できるわけですからね。
Seedによるランダム的なポーズを期待するのも面白いですが、狙ったポーズを生成するのには、OpenPoseは有効です。
ちなみに、ですが、骨格モデル用の画像は男女関係ないですから、難しいポーズは、自分で実際にやってみて、その姿を写真に収めて、骨格モデルとして使用する、というのもアリです。まだ、試してないですけど(笑)
Stable Diffusionの環境構築からLoRA作成、SDXLでの検証など、画像生成に関する記事一覧は、以下のまとめページに整理しています。




















