質問編集履歴

7

書式の改善

2024/03/04 04:46

投稿

bajapan
bajapan

スコア9

test CHANGED
File without changes
test CHANGED
@@ -13,15 +13,9 @@
13
13
 
14
14
 
15
15
 
16
- ```bvh
16
+
17
- MOTION
17
+
18
- Frames: 100
19
- Frame Time: 0.0333333
20
- ```
21
-
22
- 以下に
23
-
24
- 各要素の角度が100フレーム分ありますが、文字数制限のため6フレームのみ記入しています、
18
+ bvhのMOTION部分には各要素の角度が100フレーム分ありますが、文字数制限のため6フレームのみ記入しています、
25
19
 
26
20
 
27
21
 
@@ -247,6 +241,8 @@
247
241
 
248
242
  pass
249
243
  ```
244
+
245
+ 以下が出力されるbvhファイルです
250
246
  ```bvh
251
247
  HIERARCHY
252
248
  ROOT Base
@@ -320,8 +316,9 @@
320
316
  ![1フレーム目モーション](https://ddjkaamml8q8x.cloudfront.net/questions/2024-03-04/584ca338-69a9-4dc9-b136-620541a453d4.png)
321
317
 
322
318
 
323
- [仕様を確認したもの①]https://qiita.com/matchyy/items/ee99fb28110e4614323f
324
- [仕様を確認したもの②]https://mukai-lab.org/content/MotionCaptureDataFile.pdf
325
319
 
326
320
  ### 補足
321
+
322
+ [仕様を確認したもの①](https://qiita.com/matchyy/items/ee99fb28110e4614323f)
323
+
327
- 特にな
324
+ [仕様を確認たもの②](https://mukai-lab.org/content/MotionCaptureDataFile.pdf)

6

詳細を記入

2024/03/04 04:40

投稿

bajapan
bajapan

スコア9

test CHANGED
File without changes
test CHANGED
@@ -6,21 +6,12 @@
6
6
  動かした時におかしな挙動になってしまいます。
7
7
  MOTIONを設定せず、OFFSETのみ設定した時の初期ポーズは適切に出力できるため事前の座標取得はうまくいっていると思うのですが、MOTIONの角度を設定した時に動かした時にうまくいきません。どうすれば良いでしょうか
8
8
 
9
- ソースコードはteratailの文字数制限が9000文字でコピペできないため、角度計算の関数のみ記述いたします。
10
- 引数はどちらもnumpyの長さ3のベクトルで、角度を測りたい2つのベクトルになります。
11
- 人の腕で例えると、それぞれ
12
- vec1が肩から肘のベクトル
13
- vec2が肘から手首のベクトル
14
- になります。
15
-
16
- 座標は
17
-
18
-
19
-
20
- 手首
21
- の4箇所あり
22
- 胸は常に座標が(0,0,0)です
23
- この関数から出力され値をbvhファイルの
9
+ ちら動画の腕の動きを取得しいです
10
+ [動画](https://www.pexels.com/ja-jp/video/6003988/)
11
+ #動画の動きはmediapipeを使って取得しており、理想としてはこのような動きを取得したいです。
12
+ [出力したい動き](https://www.youtube.com/watch?v=jn2vbNM9eck)
13
+
14
+
24
15
 
25
16
  ```bvh
26
17
  MOTION
@@ -30,9 +21,7 @@
30
21
 
31
22
  以下に
32
23
 
33
- (basexyz座標),(baseからXYZrotation),(肩XYZrotation),(肘のXYZrotation)
24
+ 各要素角度が100フレーム分ありますが、文字数制限ため6フレームみ記入しています、
34
-
35
- のように100行追加しています。
36
25
 
37
26
 
38
27
 
@@ -40,9 +29,34 @@
40
29
  ### 該当のソースコード
41
30
 
42
31
  ```python
32
+ import numpy as np
33
+ import math
34
+
35
+ #numpy配列をスペースありのstring文字列に変換
36
+ def np2str(array):
37
+ for i in range(len(array)):
38
+ array[i]=round(array[i], 3)
39
+
40
+ #array[1],array[2]=array[2],array[1]
41
+
42
+ out=" ".join(map(str,array))
43
+
44
+ return out
45
+
46
+ #numpy配列をスペースありのstring文字列に変換
47
+ def np2strForList(array):
48
+ out=[]
49
+ for arr in array:
50
+ out.append(" ".join(map(str,arr)))
51
+
52
+
53
+ out=" ".join(map(str,out))
54
+
55
+
56
+ return out
57
+
43
58
 
44
59
  #xyzの角度を取得
45
- import numpy as np
46
60
  def rotxyz(vec1,vec2):
47
61
 
48
62
  #各2次元ベクトル
@@ -65,19 +79,21 @@
65
79
  zInner=np.dot(vec1xy,vec2xy)
66
80
 
67
81
  #各角度
68
- #ゼロ除算対策
82
+ #xrot=np.arccos(xInner/(vec1yzLen*vec2yzLen))
69
- with np.errstate(all='ignore'):
83
+ #yrot=np.arccos(yInner/(vec1zxLen*vec2zxLen))
84
+ #zrot=np.arccos(zInner/(vec1xyLen*vec2xyLen))
85
+
70
- xrot=(xInner/(vec1yzLen*vec2yzLen))
86
+ xrot=(xInner/(vec1yzLen*vec2yzLen))
71
- yrot=(yInner/(vec1zxLen*vec2zxLen))
87
+ yrot=(yInner/(vec1zxLen*vec2zxLen))
72
- zrot=(zInner/(vec1xyLen*vec2xyLen))
88
+ zrot=(zInner/(vec1xyLen*vec2xyLen))
73
- #割り算の分母が0の時Noneが出るので、角度を0にする
89
+
74
90
  if math.isnan(xrot):
75
91
  xrot=0
76
92
  if math.isnan(yrot):
77
93
  yrot=0
78
94
  if math.isnan(zrot):
79
95
  zrot=0
80
- #角度に変換
96
+
81
97
  xDeg=math.degrees(xrot)
82
98
  yDeg=math.degrees(yrot)
83
99
  zDeg=math.degrees(zrot)
@@ -85,8 +101,210 @@
85
101
  yDeg=round(yDeg, 3)
86
102
  zDeg=round(zDeg, 3)
87
103
  #帰り値は全てfloat型
88
- return zDeg,yDeg,xDeg
104
+ return xDeg,yDeg,zDeg
105
+
106
+ #フレーム数
107
+ frames=[[[0.167, -0.453, 0.051], [-0.128, -0.474, 0.047], [0.224, -0.255, -0.007], [-0.256, -0.29, 0.014], [0.35, -0.366, -0.179], [-0.358, -0.388, -0.155]], [[0.17, -0.453, 0.049], [-0.128, -0.475, 0.044], [0.225, -0.26, -0.018], [-0.256, -0.294, 0.006], [0.347, -0.372, -0.194], [-0.358, -0.404, -0.163]],
108
+ [[0.172, -0.453, 0.049], [-0.128, -0.475, 0.044], [0.229, -0.261, -0.019], [-0.26, -0.299, 0.006], [0.347, -0.374, -0.196], [-0.358, -0.416, -0.163]], [[0.177, -0.453, 0.054], [-0.126, -0.475, 0.052], [0.235, -0.261, -0.015], [-0.262, -0.306, 0.022], [0.352, -0.373, -0.191], [-0.359, -0.426, -0.129]],
109
+ [[0.181, -0.453, 0.051], [-0.124, -0.475, 0.047], [0.243, -0.261, -0.016], [-0.262, -0.312, 0.012], [0.354, -0.374, -0.191], [-0.355, -0.432, -0.137]], [[0.184, -0.453, 0.051], [-0.122, -0.476, 0.046], [0.248, -0.261, -0.016], [-0.263, -0.318, 0.014], [0.362, -0.374, -0.191], [-0.347, -0.437, -0.129]]]
110
+
111
+
112
+ for frame in range(len(frames)):
113
+ for i1 in range(6):
114
+ for i2 in range(3):
115
+ frames[frame][i1][i2]=round(frames[frame][i1][i2],3)
116
+ print((frames))
117
+
118
+
119
+
120
+
121
+
122
+
123
+ VectorUp=np.array([1,0,0])
124
+ Motions=[]
125
+ #フレームごとに取得
126
+ for index, landmarks in enumerate(frames):
127
+
128
+
129
+ #位置の設定。(L,Rは絶対位置、Left,Rightは相対位置)
130
+ #部位ごとに取得=========================
131
+ Base=np.array([0,0,0])
132
+ #上半身ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
133
+ LShoulder=np.array(landmarks[0])# 左肩
134
+ RShoulder=np.array(landmarks[1])# 右肩
135
+ LElbow=np.array(landmarks[2])# 左肘
136
+ RElbow=np.array(landmarks[3])# 右肘
137
+ LWrist=np.array(landmarks[4])# 左手首
138
+ RWrist=np.array(landmarks[5])# 右手首
139
+ HeartAbsol=((LShoulder+RShoulder)/2)#胸(左右の肩の中間点)
140
+
141
+
142
+ if index==0:#初期オフセット設定
143
+
144
+
145
+ #体の初期位置================================================================
146
+ LeftShoulder_origin=LShoulder-HeartAbsol#左腰
147
+ RightShoulder_origin=RShoulder-HeartAbsol#左腰
148
+ LeftElbow_origin=LElbow-LShoulder#右ひじ
149
+ RightElbow_origin=RElbow-RShoulder#左ひじ
150
+ LeftWrist_origin=LWrist-LElbow#右手首
151
+ RightWrist_origin=RWrist-RElbow#左手首
152
+
153
+
154
+ root=[0,0,0,0,0,0]#座標、回転
155
+ #腰から上半身、右足、左足の三つに分かれる
156
+ #左足================================================================
157
+ LeftShoulder=LShoulder-HeartAbsol#左腰
158
+ RightShoulder=RShoulder-HeartAbsol#左腰
159
+ LeftElbow=LElbow-LShoulder#右ひじ
160
+ RightElbow=RElbow-RShoulder#左ひじ
161
+ LeftWrist=LWrist-LElbow#右手首
162
+ RightWrist=RWrist-RElbow#左手首
163
+
164
+ #角度
165
+ #左
166
+ LeftShoulder_rot=rotxyz(VectorUp,LeftShoulder)
167
+ LeftElbow_rot=rotxyz(LeftShoulder,LeftElbow)
168
+ LeftWrist_rot=rotxyz(LeftElbow,LeftWrist)
169
+
170
+ #右
171
+ RightShoulder_rot=rotxyz(VectorUp,RightShoulder)
172
+ RightElbow_rot=rotxyz(RightShoulder,RightElbow)
173
+ RightWrist_rot=rotxyz(RightElbow,RightWrist)
174
+
175
+
176
+
177
+ #モーション作成
178
+ Motions.append(np2strForList([
179
+ np.array([0,0,0]),np.array([0,0,0]),
180
+ LeftShoulder_rot,LeftElbow_rot,LeftWrist_rot,
181
+ RightShoulder_rot,RightElbow_rot,RightWrist_rot
182
+ ]))
183
+
184
+
185
+ bvh_content_complex_japanese = f"""
186
+ HIERARCHY
187
+ ROOT Base
188
+ {{
189
+ OFFSET 0.00 0.00 0.00
190
+ CHANNELS 6 Xposition Yposition Zposition Zrotation Yrotation Xrotation
191
+ JOINT LeftShoulder
192
+ {{
193
+ OFFSET 0.00 0.00 0.00
194
+ CHANNELS 3 Zrotation Yrotation Xrotation
195
+ JOINT LeftElbow
196
+ {{
197
+ OFFSET {np2str(LeftShoulder_origin)}
198
+ CHANNELS 3 Zrotation Yrotation Xrotation
199
+ JOINT RightWrist
200
+ {{
201
+ OFFSET {np2str(LeftElbow_origin)}
202
+ CHANNELS 3 Zrotation Yrotation Xrotation
203
+ End Site
204
+ {{
205
+ OFFSET {np2str(LeftWrist_origin)}
206
+ }}
207
+ }}
208
+ }}
209
+ }}
210
+ JOINT RightShoulder
211
+ {{
212
+ OFFSET 0.00 0.00 0.00
213
+ CHANNELS 3 Zrotation Yrotation Xrotation
214
+ JOINT RightElbow
215
+ {{
216
+ OFFSET {np2str(RightShoulder_origin)}
217
+ CHANNELS 3 Zrotation Yrotation Xrotation
218
+ JOINT RightWrist
219
+ {{
220
+ OFFSET {np2str(RightElbow_origin)}
221
+ CHANNELS 3 Zrotation Yrotation Xrotation
222
+ End Site
223
+ {{
224
+ OFFSET {np2str(RightWrist_origin)}
225
+ }}
226
+ }}
227
+ }}
228
+ }}
229
+ }}
230
+ MOTION
231
+ Frames: {len(frames)}
232
+ Frame Time: 0.0333333
233
+ """
234
+
235
+
236
+
237
+
238
+ #BVHファイル書き込み
239
+ bvh_complex_japanese_file_path = './BVHfile/bvh_check.bvh'
240
+ with open(bvh_complex_japanese_file_path, 'w') as file:
241
+ file.write(bvh_content_complex_japanese.strip())
242
+ file.write("\n")#改行
243
+
244
+ for i in Motions:
245
+ file.write(i)
246
+ file.write("\n")#改行
247
+
248
+ pass
89
249
  ```
250
+ ```bvh
251
+ HIERARCHY
252
+ ROOT Base
253
+ {
254
+ OFFSET 0.00 0.00 0.00
255
+ CHANNELS 6 Xposition Yposition Zposition Zrotation Yrotation Xrotation
256
+ JOINT LeftShoulder
257
+ {
258
+ OFFSET 0.00 0.00 0.00
259
+ CHANNELS 3 Zrotation Yrotation Xrotation
260
+ JOINT LeftElbow
261
+ {
262
+ OFFSET 0.148 0.011 0.002
263
+ CHANNELS 3 Zrotation Yrotation Xrotation
264
+ JOINT RightWrist
265
+ {
266
+ OFFSET 0.057 0.198 -0.058
267
+ CHANNELS 3 Zrotation Yrotation Xrotation
268
+ End Site
269
+ {
270
+ OFFSET 0.126 -0.111 -0.172
271
+ }
272
+ }
273
+ }
274
+ }
275
+ JOINT RightShoulder
276
+ {
277
+ OFFSET 0.00 0.00 0.00
278
+ CHANNELS 3 Zrotation Yrotation Xrotation
279
+ JOINT RightElbow
280
+ {
281
+ OFFSET -0.148 -0.01 -0.002
282
+ CHANNELS 3 Zrotation Yrotation Xrotation
283
+ JOINT RightWrist
284
+ {
285
+ OFFSET -0.128 0.184 -0.033
286
+ CHANNELS 3 Zrotation Yrotation Xrotation
287
+ End Site
288
+ {
289
+ OFFSET -0.102 -0.098 -0.169
290
+ }
291
+ }
292
+ }
293
+ }
294
+ }
295
+ MOTION
296
+ Frames: 6
297
+ Frame Time: 0.0333333
298
+ 0 0 0 0 0 0 0.0 57.291 57.151 51.0 39.603 19.72 -16.282 56.699 -24.503 0.0 -57.291 -57.151 -53.507 55.67 29.297 -19.541 40.915 -8.992
299
+ 0 0 0 0 0 0 0.0 57.288 57.14 48.617 35.606 19.717 -13.207 57.107 -25.697 0.0 -57.288 -57.14 -52.07 55.192 29.548 -20.722 42.343 -11.809
300
+ 0 0 0 0 0 0 0.0 57.288 57.142 48.426 36.07 20.28 -12.94 56.952 -26.212 0.0 -57.288 -57.142 -51.933 55.316 30.933 -21.937 41.332 -13.064
301
+ 0 0 0 0 0 0 0.0 57.295 57.145 51.944 36.577 20.497 -12.6 56.935 -25.959 0.0 -57.295 -57.145 -55.276 56.031 32.594 -27.259 40.624 -12.133
302
+ 0 0 0 0 0 0 0.0 57.291 57.147 49.847 38.36 21.484 -13.486 56.356 -26.559 0.0 -57.291 -57.147 -52.964 55.717 33.78 -25.769 41.355 -11.885
303
+ 0 0 0 0 0 0 0.0 57.288 57.135 48.852 38.894 22.142 -13.486 56.317 -25.397 0.0 -57.288 -57.135 -52.458 56.075 34.838 -27.178 39.234 -12.924
304
+
305
+ ```
306
+
307
+
90
308
 
91
309
  ### 試したこと・調べたこと
92
310
  - [x] teratailやGoogle等で検索した
@@ -95,7 +313,12 @@
95
313
  - [ ] その他
96
314
 
97
315
  ##### 上記の詳細・結果
316
+
98
317
  出力したbvhファイルををblenderにインポートして動かしました。
318
+ 右が上記のbvhをインポートしたもの、左がbvhファイルのFrame Time: 0.0333333以降を削除したものです。左のような動きを出力したいです
319
+
320
+ ![1フレーム目モーション](https://ddjkaamml8q8x.cloudfront.net/questions/2024-03-04/584ca338-69a9-4dc9-b136-620541a453d4.png)
321
+
99
322
 
100
323
  [仕様を確認したもの①]https://qiita.com/matchyy/items/ee99fb28110e4614323f
101
324
  [仕様を確認したもの②]https://mukai-lab.org/content/MotionCaptureDataFile.pdf

5

書式の改正

2024/03/03 13:35

投稿

bajapan
bajapan

スコア9

test CHANGED
File without changes
test CHANGED
@@ -6,12 +6,33 @@
6
6
  動かした時におかしな挙動になってしまいます。
7
7
  MOTIONを設定せず、OFFSETのみ設定した時の初期ポーズは適切に出力できるため事前の座標取得はうまくいっていると思うのですが、MOTIONの角度を設定した時に動かした時にうまくいきません。どうすれば良いでしょうか
8
8
 
9
- ソースコードは文字制限ため、角度計算の関数のみ記述いたします。
9
+ ソースコードはteratailの文字制限が9000文字でコピペできないため、角度計算の関数のみ記述いたします。
10
10
  引数はどちらもnumpyの長さ3のベクトルで、角度を測りたい2つのベクトルになります。
11
11
  人の腕で例えると、それぞれ
12
12
  vec1が肩から肘のベクトル
13
13
  vec2が肘から手首のベクトル
14
14
  になります。
15
+
16
+ 座標は
17
+
18
+
19
+
20
+ 手首
21
+ の4箇所あり
22
+ 胸は常に座標が(0,0,0)です
23
+ この関数から出力された値をbvhファイルの
24
+
25
+ ```bvh
26
+ MOTION
27
+ Frames: 100
28
+ Frame Time: 0.0333333
29
+ ```
30
+
31
+ 以下に
32
+
33
+ (baseのxyz座標),(baseからのXYZrotation),(肩のXYZrotation),(肘のXYZrotation)
34
+
35
+ のように100行追加しています。
15
36
 
16
37
 
17
38
 

4

一部表現を訂正

2024/03/03 08:25

投稿

bajapan
bajapan

スコア9

test CHANGED
File without changes
test CHANGED
@@ -1,5 +1,6 @@
1
1
  ### 実現したいこと
2
- pythonで2つのxyzの3次元ベクトルbvhファイルを生成したいので、角度を計算して適切な値を設定したいです。
2
+ pythonで2つのxyzの3次元ベクトルbvhファイルを生成したいので、
3
+ 角度を計算してMOTIONのXrotation,Yrotation,Zrotationに適切な値を設定したいです。
3
4
 
4
5
  ### 発生している問題・分からないこと
5
6
  動かした時におかしな挙動になってしまいます。

3

一部表現を訂正

2024/03/03 08:04

投稿

bajapan
bajapan

スコア9

test CHANGED
@@ -1 +1 @@
1
- XYZの3座標のベクトルからBVHファイルを生成したい
1
+ 2つの3次元ベクトルからBVHファイルのrotation算出したい
test CHANGED
@@ -1,9 +1,9 @@
1
1
  ### 実現したいこと
2
- pythonによってxyz座標データみからbvhファイルを生成したいので、角度を計算して適切な値を設定したいです。
2
+ pythonで2つのxyzの3次元ベクトルbvhファイルを生成したいので、角度を計算して適切な値を設定したいです。
3
3
 
4
4
  ### 発生している問題・分からないこと
5
5
  動かした時におかしな挙動になってしまいます。
6
- MOTIONを設定せず、OFFSETのみ設定した時の初期ポーズは適切に出力できるため事前の座標取得はうまくいっていると思うのですが、動かした時にうまくいきません。どうすれば良いでしょうか
6
+ MOTIONを設定せず、OFFSETのみ設定した時の初期ポーズは適切に出力できるため事前の座標取得はうまくいっていると思うのですが、MOTIONの角度を設定した時に動かした時にうまくいきません。どうすれば良いでしょうか
7
7
 
8
8
  ソースコードは文字制限のため、角度計算の関数のみ記述いたします。
9
9
  引数はどちらもnumpyの長さ3のベクトルで、角度を測りたい2つのベクトルになります。
@@ -48,14 +48,14 @@
48
48
  xrot=(xInner/(vec1yzLen*vec2yzLen))
49
49
  yrot=(yInner/(vec1zxLen*vec2zxLen))
50
50
  zrot=(zInner/(vec1xyLen*vec2xyLen))
51
-
51
+ #割り算の分母が0の時Noneが出るので、角度を0にする
52
52
  if math.isnan(xrot):
53
53
  xrot=0
54
54
  if math.isnan(yrot):
55
55
  yrot=0
56
56
  if math.isnan(zrot):
57
57
  zrot=0
58
-
58
+ #角度に変換
59
59
  xDeg=math.degrees(xrot)
60
60
  yDeg=math.degrees(yrot)
61
61
  zDeg=math.degrees(zrot)

2

詳細を記入

2024/03/03 07:47

投稿

bajapan
bajapan

スコア9

test CHANGED
@@ -1 +1 @@
1
- 座標からBVHファイルを生成したい
1
+ XYZの3座標のベクトルからBVHファイルを生成したい
test CHANGED
File without changes

1

numpy mathのimportと説明を追加しました。

2024/03/02 14:15

投稿

bajapan
bajapan

スコア9

test CHANGED
File without changes
test CHANGED
@@ -6,7 +6,8 @@
6
6
  MOTIONを設定せず、OFFSETのみ設定した時の初期ポーズは適切に出力できるため事前の座標取得はうまくいっていると思うのですが、動かした時にうまくいきません。どうすれば良いでしょうか
7
7
 
8
8
  ソースコードは文字制限のため、角度計算の関数のみ記述いたします。
9
+ 引数はどちらもnumpyの長さ3のベクトルで、角度を測りたい2つのベクトルになります。
9
- 引数は人の腕で例えると、それぞれ
10
+ 人の腕で例えると、それぞれ
10
11
  vec1が肩から肘のベクトル
11
12
  vec2が肘から手首のベクトル
12
13
  になります。
@@ -19,6 +20,7 @@
19
20
  ```python
20
21
 
21
22
  #xyzの角度を取得
23
+ import numpy as np
22
24
  def rotxyz(vec1,vec2):
23
25
 
24
26
  #各2次元ベクトル