ボーンの位置座標取得

  • このフォーラムに新しいトピックを立てることはできません
  • このフォーラムではゲスト投稿が禁止されています

投稿ツリー



前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2015/9/7 11:13
sorabou  新米   投稿数: 3
お世話になります。最近Blenderを使い始めた初心者の者です。

レンダリング画像中での人モデルのボーンの位置情報を取得したいと思っているのですが、
Pythonのスクリプトなどで3Dでのボーンの座標を取得し、
それをレンダリング画像中での座標に変換して出力することなどは可能でしょうか?

十分な状況説明になっていないかもしれませんが、
やり方をご存知の方がいらっしゃいましたら、よろしくお願いいたします。

バージョン:Blender2.72b
PC:Windows 7 Professional
プロセッサ:Intel Core i7-2600, 3.40GHz
16GBメモリ, 64bitOS
投票数:5 平均点:2.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 .2 | 投稿日時 2015/9/7 12:43
完全無欠猫  長老 居住地: 兵庫  投稿数: 750
3D座標がビュー内に投影された時の2D座標が知りたいということでしょうか・・・。
その前提で書いています。

以下はPose boneでの話です。
子Boneは親Boneの座標空間にあります。
従って親Boneを遡ってObject空間の座標を取得して、それをObjectのmatrix_worldでワールド座標に変換します。

この部分は知らなくても・・・と、いうかいろいろ考えすぎて分からなくなるかもしれないので・・・削除。
例えば、bone1>bone2>bone3という構造の場合(bone1が最初のboneでbone2はbone1の子供という図式です)
obj = bpy.data.objects['AAAAAA']
算出方法に誤りがあったので訂正。matrixは最終的なBoneのmatrixだったので・・・
bone1mat = obj.pose.bones['bone1'].matrix
bone2mat = obj.pose.bones['bone2'].matrix
bone3mat = obj.pose.bones['bone3'].matrix
bone3loc = obj.pose.bones['bone3'].location
Lbone3mat = bone3mat * bone2mat.transposed() * bone1mat.transposed()
worldBone3Loc = obj.matrix_world * Lbone3mat * bone3loc


正しくは、こうです。
bone3loc = obj.pose.bones['bone3'].head
worldBone3Loc = obj.matrix_world * bone3loc

これを該当ビュー内の2D座標に変換するにはbpy_extrasパッケージを使います。
bpy_extras.view3d_utils.location_3d_to_region_2d(region, rv3d, coord, default=None)という関数があります。
coordが上記で求めた3D座標です。
regionとrv3dは該当スクリーンから求めます。
これは各データのtypeを比較して取得した方がいいと思います。
scr = bpy.context.screen

scr.areas[5].typeが'VIEW3D'になります。
scr.areas[5].regions[4].typeが'WINDOW'になります。
scr.areas[5].spaces[0].typeが'VIEW_3D'になります。

ですので、ワールド座標のVector((0,0,0))を該当ビューで求める場合
ar = scr.areas[5]
rLoc = bpy_extras.view3d_utils.location_3d_to_region_2d(ar.regions[4], ar.spaces[0].region_3d, Vector((0,0,0)))
rLocが該当ビュー内の相対座標になるはずです。

しかし、確認していないので間違っているかもしれませんが・・・・。

== 追記 ==
あぁぁぁ・・・・カメラビューかなぁ・・。
カメラビューの場合はこっちの関数を・・・。
bpy_extras.object_utils.world_to_camera_view(scene, obj, coord)
objはCamera objectです。

== 追記の追記 ==
書かなくても分かるかな?と思ったので書かなかったのですが・・・初心者の方という事だったのでもう少し書きます。
scene = bpy.context.scene
camera = scene.camera
rLoc = bpy_extras.object_utils.world_to_camera_view(scene, camera, worldBone3Loc)
renderSetting = scene.render
imagePosX = renderSetting.resolution_x * rLoc.x
imagePosY = renderSetting.resolution_y * rLoc.y
imagePosX, imagePosYがレンダリングイメージ内の座標になると思います。
投票数:8 平均点:6.25
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2015/9/7 21:18
Shige  長老   投稿数: 306
ひや〜、素晴らしい。感服つかまつりました。

--
-- Shige

投票数:4 平均点:2.50
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2015/9/8 1:15
sorabou  新米   投稿数: 3
お返事が遅れまして申し訳ありません。
丁寧なご説明、ありがとうございます!

ビュー内に投影された時の2D座標でなく、カメラビューでみたときの座標です。
追記の方を参考にさせていただきました。
world_to_camera_view()なんてピンポイントな関数があったのですね…笑

ワールド座標での3D位置座標は取得できたと思うのですが、
imagePosX, Yを計算してみるとレンダリング画像中の位置とはずれているようだったので、
world_to_camera_view()の出力を見てみるとz座標を含めた3次元ベクトルになっていました。

この関数はカメラビューからみたときの2D座標を出力するものではないのでしょうか…?


投票数:14 平均点:7.86
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2015/9/8 10:40
完全無欠猫  長老 居住地: 兵庫  投稿数: 750
お詫びと訂正
ワールド座標の算出方法が間違っていたのでお詫びします。
原文も訂正してありますが、改めてこちらにも書きます。
bone3loc = obj.pose.bones['bone3'].head
worldBone3Loc = obj.matrix_world * bone3loc
worldBone3Locがワールド座標です。

== 返信に対する回答 ==
引用:
world_to_camera_view()の出力を見てみるとz座標を含めた3次元ベクトルになっていました。
この関数はカメラビューからみたときの2D座標を出力するものではないのでしょうか…?
ん〜、公式サイトのBlender 2.75.4 - API documentationを見てから質問してくれたらと・・・思いましたが。
Blender Official Online Manual
戻り値はこのように書かれています。
Returns: a vector where X and Y map to the view plane and Z is the depth on the view axis.
Vectorが戻りますが、x,yがカメラビューの2Dマップ上の相対位置を示し、zはその点における深度を示しています。
ですので、回答内でZ値については何も言及していなかったはずです。
回答内で完全なコードを書くことはありません。指針を示すコードです。
それは使用者の設定で必要な項目が異なるからです。
レンダリングイメージ中の位置を計算する式内にイメージのサイズの倍率を示す項目が含まれていません。
他にも設定によっては縦横比に対する考慮などもあるかと思います。
それらは作る側が考慮すべき項目です。
回答内に示されたコードは自ら検証すべきで、そのまま使用して動かない、又は結果が違うというのはどうでしょうか・・・。
明らかに示された内容が間違っている場合はその限りではありませんが・・・。
それを自分の理解に変えるにはそれが何故そのようにすべきなのかを考えることが必要です。
その為には知らない関数ならそれの意味する内容を調べるのは当然だと思います。
そして、目の前の結果が異なるのであればその原因を調べるのは作り手です。
最後に質問の意図がレンダリングイメージでの位置が異なっていたということであれば提示する情報が違うのではないですか?

== 以下は個人的な意見であり、このサイトの公式見解とは無関係です ==
個人的に公式サイトが提示している公式マニュアルを一読もしていないような質問にはあまり回答しません。(初心者の方を除いて)
しかしながら、公式サイトが提示している資料が適切でない事もあり、調べるのが不得手な方もいらっしゃいます。(これは、けなしているのではありません)
私もBlenderに触れてしばらくはどこにどのような情報があるのかも知らない時期がありましたので・・・。
ですので、辛辣な物言いに聞こえるかも知れませんが、ご自分で調べる事を前提にコメントが書かれている事をご理解頂けたらと思います。
投票数:17 平均点:8.82
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2015/9/8 10:44
完全無欠猫  長老 居住地: 兵庫  投稿数: 750
Shigeさん・・・どこか間違ってるかもしれませんよ・・・。
Shigeさんが暇なら・・・検証してもらっても・・・・

冷やかしのコメントに感謝致します。

== 追記 ==
間違ってました・・・DirectXの変換の部分を書いてました。
あぁ、DirectXというと・・これも又語弊があるなぁ・・・。
投票数:7 平均点:5.71
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2015/9/8 15:25
sorabou  新米   投稿数: 3
出力のZは深度だったのですね。
勉強不足のままオフィシャルな情報を質問してしまい、失礼いたしました。

しかし、お蔭様で今回目標としていたことを達成できました。
どうもありがとうございましたm(_ _)m
一緒に掲載して頂いたドキュメンテーションなどを参考に、
自分でももう少し勉強したいと思います。


投票数:4 平均点:5.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2015/9/8 17:29
完全無欠猫  長老 居住地: 兵庫  投稿数: 750
ワールド座標の算出方法については、申し訳なかったです。
ちょっと別件で調べていたものと近しかったので、それに使っていた式を提示したのですが
再度質問されてモデルを見てみたら異なるものでしたので・・・・修正させてもらいました。
不躾な書き様で申し訳ないとは思いましたが、調べ様が分かればご自分で今後もされるだろうなと思い書かせてもらいました。
このサイトのクイックリンクに示されている所には有用な情報があるはずですので、利用されるのがいいかと思います。

投票数:5 平均点:4.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2015/9/9 21:05
Shige  長老   投稿数: 306
いやいや、それだけの理解力があったら自分のプロジェクトもガンガン進むのにと思ってしまいますよ、まったく。
爪の垢でも煎じて飲めば、少しはマシになるかもしれませんので、お手数ですが以下の住所まで送っていただけ(以下略)

--
-- Shige

投票数:10 平均点:8.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2015/9/10 7:56
完全無欠猫  長老 居住地: 兵庫  投稿数: 750
そんなもの送らなくても・・・Shigeさんの周りにも猫が・・・・。
昔から「猫の手も借りたい」と言いますしねぇ・・・。
あ、でもあれは誰でもいいという意味あいだからなぁ・・・。
投票数:11 平均点:7.27

  条件検索へ


ログイン

ユーザ名:

パスワード:



パスワード紛失

クイックリンク

2021/07/01版
●Blender.org
BlenderFoundation
- Blenderのダウンロード
- 公式チュート等
- 公式マニュアル(和訳)

●ニュース(英文)
BlenderNation

●Blenderコミュニティ
blenderartists.org

●Blender Q&A
- Blender Stack Exchange

●テストビルド
Buildbot(自動生成)


●開発関連
公式開発サイト
Blender開発blog
Blender Wiki