Commit
·
8de0c20
1
Parent(s):
1c1d010
feat: Enhance pose editor with improved hand data logging and template selection functionality
Browse files- Added detailed logging for hand data preparation and drawing in pose_editor.js.
- Implemented a new template selection feature that consolidates multiple templates into one with a manual update button.
- Introduced a new JSON file (3heads.json) containing pose data for 3-headed characters.
- Updated poses.json to include structured pose data for 2-head and 3-head characters.
- Improved error handling and user experience during template loading and pose updates.
- .gitignore +2 -2
- 3heads.json +477 -0
- app.py +107 -47
- issues/039_テンプレート選択機能改善.md +136 -0
- static/pose_editor.js +50 -3
- templates/poses.json +109 -0
.gitignore
CHANGED
|
@@ -95,10 +95,10 @@ output/
|
|
| 95 |
*.avi
|
| 96 |
*.mov
|
| 97 |
*.jsonl
|
| 98 |
-
*.json
|
| 99 |
!template_pose.json
|
| 100 |
# testプログラム
|
| 101 |
-
|
| 102 |
|
| 103 |
# HuggingFace Spacesデプロイ関連
|
| 104 |
.space/
|
|
|
|
| 95 |
*.avi
|
| 96 |
*.mov
|
| 97 |
*.jsonl
|
| 98 |
+
test*.json
|
| 99 |
!template_pose.json
|
| 100 |
# testプログラム
|
| 101 |
+
test*.py
|
| 102 |
|
| 103 |
# HuggingFace Spacesデプロイ関連
|
| 104 |
.space/
|
3heads.json
ADDED
|
@@ -0,0 +1,477 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bodies": {
|
| 3 |
+
"candidate": [
|
| 4 |
+
[
|
| 5 |
+
253.99999999999997,
|
| 6 |
+
148.66666666666663,
|
| 7 |
+
1.0,
|
| 8 |
+
0
|
| 9 |
+
],
|
| 10 |
+
[
|
| 11 |
+
256.33333333333337,
|
| 12 |
+
210.0,
|
| 13 |
+
1.0,
|
| 14 |
+
0
|
| 15 |
+
],
|
| 16 |
+
[
|
| 17 |
+
205.33333333333334,
|
| 18 |
+
209.33333333333331,
|
| 19 |
+
1.0,
|
| 20 |
+
0
|
| 21 |
+
],
|
| 22 |
+
[
|
| 23 |
+
184.66666666666666,
|
| 24 |
+
261.99999999999994,
|
| 25 |
+
1.0,
|
| 26 |
+
0
|
| 27 |
+
],
|
| 28 |
+
[
|
| 29 |
+
165.33333333333334,
|
| 30 |
+
310.6666666666667,
|
| 31 |
+
1.0,
|
| 32 |
+
0
|
| 33 |
+
],
|
| 34 |
+
[
|
| 35 |
+
307.33333333333337,
|
| 36 |
+
210.66666666666669,
|
| 37 |
+
1.0,
|
| 38 |
+
0
|
| 39 |
+
],
|
| 40 |
+
[
|
| 41 |
+
327.33333333333337,
|
| 42 |
+
262.6666666666667,
|
| 43 |
+
1.0,
|
| 44 |
+
0
|
| 45 |
+
],
|
| 46 |
+
[
|
| 47 |
+
344.66666666666674,
|
| 48 |
+
309.99999999999994,
|
| 49 |
+
1.0,
|
| 50 |
+
0
|
| 51 |
+
],
|
| 52 |
+
[
|
| 53 |
+
223.33333333333334,
|
| 54 |
+
339.3333333333333,
|
| 55 |
+
1.0,
|
| 56 |
+
0
|
| 57 |
+
],
|
| 58 |
+
[
|
| 59 |
+
224.66666666666666,
|
| 60 |
+
399.3333333333334,
|
| 61 |
+
1.0,
|
| 62 |
+
0
|
| 63 |
+
],
|
| 64 |
+
[
|
| 65 |
+
234.66666666666666,
|
| 66 |
+
470.00000000000006,
|
| 67 |
+
1.0,
|
| 68 |
+
0
|
| 69 |
+
],
|
| 70 |
+
[
|
| 71 |
+
286.66666666666674,
|
| 72 |
+
339.3333333333333,
|
| 73 |
+
1.0,
|
| 74 |
+
0
|
| 75 |
+
],
|
| 76 |
+
[
|
| 77 |
+
281.33333333333337,
|
| 78 |
+
400.00000000000006,
|
| 79 |
+
1.0,
|
| 80 |
+
0
|
| 81 |
+
],
|
| 82 |
+
[
|
| 83 |
+
274.66666666666674,
|
| 84 |
+
470.00000000000006,
|
| 85 |
+
1.0,
|
| 86 |
+
0
|
| 87 |
+
],
|
| 88 |
+
[
|
| 89 |
+
233.99999999999997,
|
| 90 |
+
133.99999999999994,
|
| 91 |
+
1.0,
|
| 92 |
+
0
|
| 93 |
+
],
|
| 94 |
+
[
|
| 95 |
+
271.33333333333337,
|
| 96 |
+
133.99999999999994,
|
| 97 |
+
1.0,
|
| 98 |
+
0
|
| 99 |
+
],
|
| 100 |
+
[
|
| 101 |
+
206.66666666666666,
|
| 102 |
+
150.66666666666663,
|
| 103 |
+
1.0,
|
| 104 |
+
0
|
| 105 |
+
],
|
| 106 |
+
[
|
| 107 |
+
298.0,
|
| 108 |
+
150.66666666666663,
|
| 109 |
+
1.0,
|
| 110 |
+
0
|
| 111 |
+
],
|
| 112 |
+
[
|
| 113 |
+
228.0,
|
| 114 |
+
479.33333333333337,
|
| 115 |
+
1.0,
|
| 116 |
+
0
|
| 117 |
+
],
|
| 118 |
+
[
|
| 119 |
+
283.33333333333337,
|
| 120 |
+
478.66666666666674,
|
| 121 |
+
1.0,
|
| 122 |
+
0
|
| 123 |
+
]
|
| 124 |
+
],
|
| 125 |
+
"subset": []
|
| 126 |
+
},
|
| 127 |
+
"hands": [
|
| 128 |
+
[
|
| 129 |
+
344.66666666666674,
|
| 130 |
+
311.99999999999994,
|
| 131 |
+
0.7150347828865051,
|
| 132 |
+
339.33333333333337,
|
| 133 |
+
321.99999999999994,
|
| 134 |
+
0.7231502532958984,
|
| 135 |
+
333.33333333333337,
|
| 136 |
+
331.3333333333333,
|
| 137 |
+
0.661381721496582,
|
| 138 |
+
331.33333333333337,
|
| 139 |
+
339.99999999999994,
|
| 140 |
+
0.6448965668678284,
|
| 141 |
+
330.0,
|
| 142 |
+
349.3333333333333,
|
| 143 |
+
0.591521143913269,
|
| 144 |
+
350.0,
|
| 145 |
+
332.6666666666667,
|
| 146 |
+
0.6919199228286743,
|
| 147 |
+
354.0,
|
| 148 |
+
341.99999999999994,
|
| 149 |
+
0.6912438273429871,
|
| 150 |
+
358.0,
|
| 151 |
+
347.99999999999994,
|
| 152 |
+
0.6884741187095642,
|
| 153 |
+
361.33333333333337,
|
| 154 |
+
353.3333333333333,
|
| 155 |
+
0.705511212348938,
|
| 156 |
+
357.33333333333337,
|
| 157 |
+
329.3333333333333,
|
| 158 |
+
0.7716554403305054,
|
| 159 |
+
363.33333333333337,
|
| 160 |
+
339.3333333333333,
|
| 161 |
+
0.7899695038795471,
|
| 162 |
+
367.33333333333337,
|
| 163 |
+
347.3333333333333,
|
| 164 |
+
0.7758855223655701,
|
| 165 |
+
370.0,
|
| 166 |
+
353.99999999999994,
|
| 167 |
+
0.7775080800056458,
|
| 168 |
+
363.33333333333337,
|
| 169 |
+
326.6666666666667,
|
| 170 |
+
0.789682924747467,
|
| 171 |
+
369.33333333333337,
|
| 172 |
+
335.99999999999994,
|
| 173 |
+
0.7895171046257019,
|
| 174 |
+
372.0,
|
| 175 |
+
343.3333333333333,
|
| 176 |
+
0.7826341390609741,
|
| 177 |
+
374.0,
|
| 178 |
+
349.99999999999994,
|
| 179 |
+
0.7542178630828857,
|
| 180 |
+
368.66666666666674,
|
| 181 |
+
323.99999999999994,
|
| 182 |
+
0.7270801067352295,
|
| 183 |
+
372.66666666666674,
|
| 184 |
+
330.6666666666667,
|
| 185 |
+
0.7413800358772278,
|
| 186 |
+
376.0,
|
| 187 |
+
337.99999999999994,
|
| 188 |
+
0.7292997241020203,
|
| 189 |
+
378.0,
|
| 190 |
+
343.99999999999994,
|
| 191 |
+
0.7108736634254456
|
| 192 |
+
],
|
| 193 |
+
[
|
| 194 |
+
165.33333333333334,
|
| 195 |
+
312.6666666666667,
|
| 196 |
+
0.7797001600265503,
|
| 197 |
+
170.66666666666666,
|
| 198 |
+
321.99999999999994,
|
| 199 |
+
0.7401540279388428,
|
| 200 |
+
175.33333333333334,
|
| 201 |
+
331.99999999999994,
|
| 202 |
+
0.7077389359474182,
|
| 203 |
+
173.33333333333334,
|
| 204 |
+
340.6666666666667,
|
| 205 |
+
0.7360478043556213,
|
| 206 |
+
173.33333333333334,
|
| 207 |
+
347.99999999999994,
|
| 208 |
+
0.7185596227645874,
|
| 209 |
+
160.66666666666666,
|
| 210 |
+
332.6666666666667,
|
| 211 |
+
0.7588577270507812,
|
| 212 |
+
155.99999999999997,
|
| 213 |
+
341.99999999999994,
|
| 214 |
+
0.7737218141555786,
|
| 215 |
+
152.66666666666666,
|
| 216 |
+
347.99999999999994,
|
| 217 |
+
0.7760618329048157,
|
| 218 |
+
148.66666666666666,
|
| 219 |
+
352.6666666666667,
|
| 220 |
+
0.7934918403625488,
|
| 221 |
+
153.99999999999997,
|
| 222 |
+
329.99999999999994,
|
| 223 |
+
0.8451609015464783,
|
| 224 |
+
147.99999999999997,
|
| 225 |
+
339.99999999999994,
|
| 226 |
+
0.8416674733161926,
|
| 227 |
+
143.33333333333334,
|
| 228 |
+
347.3333333333333,
|
| 229 |
+
0.8654172420501709,
|
| 230 |
+
139.99999999999997,
|
| 231 |
+
352.6666666666667,
|
| 232 |
+
0.829170823097229,
|
| 233 |
+
147.99999999999997,
|
| 234 |
+
326.6666666666667,
|
| 235 |
+
0.8563532829284668,
|
| 236 |
+
143.33333333333334,
|
| 237 |
+
335.99999999999994,
|
| 238 |
+
0.8371527194976807,
|
| 239 |
+
138.66666666666666,
|
| 240 |
+
343.3333333333333,
|
| 241 |
+
0.8210606575012207,
|
| 242 |
+
134.66666666666666,
|
| 243 |
+
348.6666666666667,
|
| 244 |
+
0.7967222929000854,
|
| 245 |
+
143.99999999999997,
|
| 246 |
+
323.3333333333333,
|
| 247 |
+
0.8345107436180115,
|
| 248 |
+
139.99999999999997,
|
| 249 |
+
329.3333333333333,
|
| 250 |
+
0.7522804737091064,
|
| 251 |
+
135.99999999999997,
|
| 252 |
+
335.99999999999994,
|
| 253 |
+
0.7406725883483887,
|
| 254 |
+
132.66666666666666,
|
| 255 |
+
341.3333333333333,
|
| 256 |
+
0.7635241746902466
|
| 257 |
+
]
|
| 258 |
+
],
|
| 259 |
+
"faces": [
|
| 260 |
+
[
|
| 261 |
+
216.66666666666666,
|
| 262 |
+
135.99999999999994,
|
| 263 |
+
0.36343619227409363,
|
| 264 |
+
217.33333333333334,
|
| 265 |
+
149.33333333333331,
|
| 266 |
+
0.3816818594932556,
|
| 267 |
+
219.33333333333334,
|
| 268 |
+
157.33333333333331,
|
| 269 |
+
0.42397695779800415,
|
| 270 |
+
221.99999999999997,
|
| 271 |
+
165.33333333333331,
|
| 272 |
+
0.44912877678871155,
|
| 273 |
+
226.66666666666666,
|
| 274 |
+
173.99999999999994,
|
| 275 |
+
0.46479764580726624,
|
| 276 |
+
231.99999999999997,
|
| 277 |
+
179.99999999999994,
|
| 278 |
+
0.42750057578086853,
|
| 279 |
+
238.66666666666666,
|
| 280 |
+
182.66666666666663,
|
| 281 |
+
0.4347080588340759,
|
| 282 |
+
245.33333333333334,
|
| 283 |
+
185.33333333333331,
|
| 284 |
+
0.4085705578327179,
|
| 285 |
+
253.33333333333334,
|
| 286 |
+
187.99999999999994,
|
| 287 |
+
0.39466774463653564,
|
| 288 |
+
262.0,
|
| 289 |
+
185.99999999999994,
|
| 290 |
+
0.4313513934612274,
|
| 291 |
+
269.33333333333337,
|
| 292 |
+
182.66666666666663,
|
| 293 |
+
0.4474577009677887,
|
| 294 |
+
276.0,
|
| 295 |
+
180.66666666666663,
|
| 296 |
+
0.4354158639907837,
|
| 297 |
+
280.0,
|
| 298 |
+
173.99999999999994,
|
| 299 |
+
0.4418158233165741,
|
| 300 |
+
286.0,
|
| 301 |
+
165.99999999999994,
|
| 302 |
+
0.40984541177749634,
|
| 303 |
+
288.0,
|
| 304 |
+
155.33333333333331,
|
| 305 |
+
0.3851367235183716,
|
| 306 |
+
289.33333333333337,
|
| 307 |
+
149.99999999999994,
|
| 308 |
+
0.35478973388671875,
|
| 309 |
+
290.0,
|
| 310 |
+
136.66666666666663,
|
| 311 |
+
0.3434315025806427,
|
| 312 |
+
221.99999999999997,
|
| 313 |
+
131.33333333333331,
|
| 314 |
+
0.3179595470428467,
|
| 315 |
+
228.66666666666666,
|
| 316 |
+
129.33333333333331,
|
| 317 |
+
0.304362028837204,
|
| 318 |
+
0.0,
|
| 319 |
+
0.0,
|
| 320 |
+
0.0,
|
| 321 |
+
238.66666666666666,
|
| 322 |
+
123.33333333333331,
|
| 323 |
+
0.3022729754447937,
|
| 324 |
+
0.0,
|
| 325 |
+
0.0,
|
| 326 |
+
0.0,
|
| 327 |
+
262.0,
|
| 328 |
+
123.33333333333331,
|
| 329 |
+
0.3105626106262207,
|
| 330 |
+
267.33333333333337,
|
| 331 |
+
122.66666666666663,
|
| 332 |
+
0.30489420890808105,
|
| 333 |
+
272.66666666666674,
|
| 334 |
+
122.66666666666663,
|
| 335 |
+
0.30186206102371216,
|
| 336 |
+
278.0,
|
| 337 |
+
129.99999999999994,
|
| 338 |
+
0.30828186869621277,
|
| 339 |
+
284.66666666666674,
|
| 340 |
+
131.33333333333331,
|
| 341 |
+
0.3039014935493469,
|
| 342 |
+
252.66666666666666,
|
| 343 |
+
133.33333333333331,
|
| 344 |
+
0.33224114775657654,
|
| 345 |
+
253.33333333333334,
|
| 346 |
+
135.99999999999994,
|
| 347 |
+
0.35275089740753174,
|
| 348 |
+
253.99999999999997,
|
| 349 |
+
141.99999999999994,
|
| 350 |
+
0.33941948413848877,
|
| 351 |
+
253.99999999999997,
|
| 352 |
+
148.66666666666663,
|
| 353 |
+
0.3312435448169708,
|
| 354 |
+
246.66666666666666,
|
| 355 |
+
153.33333333333331,
|
| 356 |
+
0.331066370010376,
|
| 357 |
+
250.66666666666666,
|
| 358 |
+
153.99999999999994,
|
| 359 |
+
0.33620479702949524,
|
| 360 |
+
253.33333333333334,
|
| 361 |
+
154.66666666666663,
|
| 362 |
+
0.32499319314956665,
|
| 363 |
+
257.33333333333337,
|
| 364 |
+
154.66666666666663,
|
| 365 |
+
0.345694363117218,
|
| 366 |
+
261.33333333333337,
|
| 367 |
+
154.66666666666663,
|
| 368 |
+
0.35932013392448425,
|
| 369 |
+
227.99999999999997,
|
| 370 |
+
134.66666666666663,
|
| 371 |
+
0.35944992303848267,
|
| 372 |
+
231.99999999999997,
|
| 373 |
+
132.66666666666663,
|
| 374 |
+
0.34046822786331177,
|
| 375 |
+
237.33333333333334,
|
| 376 |
+
132.66666666666663,
|
| 377 |
+
0.3438405692577362,
|
| 378 |
+
243.33333333333334,
|
| 379 |
+
134.66666666666663,
|
| 380 |
+
0.34850671887397766,
|
| 381 |
+
237.33333333333334,
|
| 382 |
+
135.99999999999994,
|
| 383 |
+
0.35241225361824036,
|
| 384 |
+
231.99999999999997,
|
| 385 |
+
136.66666666666663,
|
| 386 |
+
0.3446846604347229,
|
| 387 |
+
264.0,
|
| 388 |
+
134.66666666666663,
|
| 389 |
+
0.35195866227149963,
|
| 390 |
+
268.0,
|
| 391 |
+
131.99999999999994,
|
| 392 |
+
0.3443024456501007,
|
| 393 |
+
272.66666666666674,
|
| 394 |
+
131.99999999999994,
|
| 395 |
+
0.34244057536125183,
|
| 396 |
+
277.33333333333337,
|
| 397 |
+
134.66666666666663,
|
| 398 |
+
0.33403435349464417,
|
| 399 |
+
273.33333333333337,
|
| 400 |
+
135.99999999999994,
|
| 401 |
+
0.3441479802131653,
|
| 402 |
+
268.0,
|
| 403 |
+
135.99999999999994,
|
| 404 |
+
0.3523240089416504,
|
| 405 |
+
241.99999999999997,
|
| 406 |
+
165.99999999999994,
|
| 407 |
+
0.3805367350578308,
|
| 408 |
+
244.66666666666666,
|
| 409 |
+
162.66666666666663,
|
| 410 |
+
0.3476058840751648,
|
| 411 |
+
251.33333333333334,
|
| 412 |
+
161.33333333333331,
|
| 413 |
+
0.3350098133087158,
|
| 414 |
+
253.33333333333334,
|
| 415 |
+
161.99999999999994,
|
| 416 |
+
0.33215898275375366,
|
| 417 |
+
255.99999999999997,
|
| 418 |
+
161.99999999999994,
|
| 419 |
+
0.3394817113876343,
|
| 420 |
+
262.66666666666674,
|
| 421 |
+
162.66666666666663,
|
| 422 |
+
0.3805198073387146,
|
| 423 |
+
267.33333333333337,
|
| 424 |
+
165.33333333333331,
|
| 425 |
+
0.38708436489105225,
|
| 426 |
+
264.66666666666663,
|
| 427 |
+
169.99999999999994,
|
| 428 |
+
0.3987838327884674,
|
| 429 |
+
260.0,
|
| 430 |
+
172.66666666666663,
|
| 431 |
+
0.39329320192337036,
|
| 432 |
+
253.99999999999997,
|
| 433 |
+
173.33333333333331,
|
| 434 |
+
0.3859204947948456,
|
| 435 |
+
249.33333333333334,
|
| 436 |
+
171.99999999999994,
|
| 437 |
+
0.37775635719299316,
|
| 438 |
+
244.66666666666666,
|
| 439 |
+
169.33333333333331,
|
| 440 |
+
0.38992202281951904,
|
| 441 |
+
243.33333333333334,
|
| 442 |
+
165.99999999999994,
|
| 443 |
+
0.37453481554985046,
|
| 444 |
+
247.99999999999997,
|
| 445 |
+
163.33333333333331,
|
| 446 |
+
0.3382393717765808,
|
| 447 |
+
253.33333333333334,
|
| 448 |
+
163.33333333333331,
|
| 449 |
+
0.33168619871139526,
|
| 450 |
+
260.66666666666674,
|
| 451 |
+
163.33333333333331,
|
| 452 |
+
0.35072460770606995,
|
| 453 |
+
266.0,
|
| 454 |
+
165.33333333333331,
|
| 455 |
+
0.3812493085861206,
|
| 456 |
+
261.33333333333337,
|
| 457 |
+
168.66666666666663,
|
| 458 |
+
0.4090779423713684,
|
| 459 |
+
253.99999999999997,
|
| 460 |
+
168.66666666666663,
|
| 461 |
+
0.39178723096847534,
|
| 462 |
+
248.66666666666666,
|
| 463 |
+
168.66666666666663,
|
| 464 |
+
0.3850829601287842
|
| 465 |
+
]
|
| 466 |
+
],
|
| 467 |
+
"resolution": [
|
| 468 |
+
512,
|
| 469 |
+
512
|
| 470 |
+
],
|
| 471 |
+
"metadata": {
|
| 472 |
+
"format": "dwpose-editor",
|
| 473 |
+
"version": "1.0",
|
| 474 |
+
"exported_at": "2025-06-13T08:21:24",
|
| 475 |
+
"description": "2頭身・3頭身キャラクター用ポーズデータ"
|
| 476 |
+
}
|
| 477 |
+
}
|
app.py
CHANGED
|
@@ -69,12 +69,14 @@ def main():
|
|
| 69 |
# テンプレートポーズ選択
|
| 70 |
template_dropdown = gr.Dropdown(
|
| 71 |
label="テンプレートポーズ",
|
| 72 |
-
choices=[
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
|
|
|
|
|
|
| 78 |
)
|
| 79 |
|
| 80 |
# JSONファイルアップロード
|
|
@@ -282,49 +284,107 @@ def main():
|
|
| 282 |
global _current_poses, _current_frame_index
|
| 283 |
|
| 284 |
try:
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
"
|
| 293 |
-
"
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 299 |
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
"pose_keypoints_2d": [],
|
| 305 |
-
"hand_left_keypoints_2d": pose_data.get('hands', [[], []])[0] if pose_data.get('hands') else [],
|
| 306 |
-
"hand_right_keypoints_2d": pose_data.get('hands', [[], []])[1] if pose_data.get('hands') and len(pose_data['hands']) > 1 else [],
|
| 307 |
-
"face_keypoints_2d": pose_data.get('faces', [[]])[0] if pose_data.get('faces') else []
|
| 308 |
}
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
|
|
|
|
| 325 |
|
| 326 |
notify_success(f"{template_name}を読み込みました")
|
| 327 |
-
return
|
| 328 |
else:
|
| 329 |
notify_error("テンプレートが見つかりません")
|
| 330 |
return None, {}
|
|
@@ -754,8 +814,8 @@ def main():
|
|
| 754 |
outputs=[js_executor]
|
| 755 |
)
|
| 756 |
|
| 757 |
-
#
|
| 758 |
-
|
| 759 |
fn=load_template_pose,
|
| 760 |
inputs=[template_dropdown],
|
| 761 |
outputs=[output_json, pose_data]
|
|
|
|
| 69 |
# テンプレートポーズ選択
|
| 70 |
template_dropdown = gr.Dropdown(
|
| 71 |
label="テンプレートポーズ",
|
| 72 |
+
choices=["3頭身立ちポーズ"],
|
| 73 |
+
value="3頭身立ちポーズ"
|
| 74 |
+
)
|
| 75 |
+
|
| 76 |
+
# ポーズ更新ボタン
|
| 77 |
+
template_update_btn = gr.Button(
|
| 78 |
+
"🔄 ポーズ更新",
|
| 79 |
+
variant="secondary"
|
| 80 |
)
|
| 81 |
|
| 82 |
# JSONファイルアップロード
|
|
|
|
| 284 |
global _current_poses, _current_frame_index
|
| 285 |
|
| 286 |
try:
|
| 287 |
+
# 3頭身テンプレートの場合は3heads.jsonを使用
|
| 288 |
+
if template_name == "3頭身立ちポーズ":
|
| 289 |
+
templates_path = os.path.join(os.path.dirname(__file__), "3heads.json")
|
| 290 |
+
with open(templates_path, "r", encoding="utf-8") as f:
|
| 291 |
+
pose_data = json.load(f)
|
| 292 |
+
else:
|
| 293 |
+
# 従来のテンプレート処理
|
| 294 |
+
templates_path = os.path.join(os.path.dirname(__file__), "templates", "poses.json")
|
| 295 |
+
with open(templates_path, "r", encoding="utf-8") as f:
|
| 296 |
+
templates = json.load(f)
|
| 297 |
+
|
| 298 |
+
# テンプレート名をキーに変換
|
| 299 |
+
template_key_map = {
|
| 300 |
+
"2頭身立ちポーズ": "2_head_standing",
|
| 301 |
+
"2頭身座りポーズ": "2_head_sitting"
|
| 302 |
+
}
|
| 303 |
+
|
| 304 |
+
template_key = template_key_map.get(template_name)
|
| 305 |
+
if template_key and template_key in templates["poses"]:
|
| 306 |
+
pose_data = templates["poses"][template_key]["data"]
|
| 307 |
+
else:
|
| 308 |
+
notify_error("テンプレートが見つかりません")
|
| 309 |
+
return None, {}
|
| 310 |
+
|
| 311 |
+
if pose_data:
|
| 312 |
+
# 3heads.jsonの場合は直接フォーマット、templates/poses.jsonの場合は.dataアクセス
|
| 313 |
+
if template_name == "3頭身立ちポーズ":
|
| 314 |
+
# 3heads.jsonは直接DWPoseフォーマット
|
| 315 |
+
actual_pose_data = pose_data
|
| 316 |
+
else:
|
| 317 |
+
# templates/poses.jsonの場合は.dataアクセス
|
| 318 |
+
actual_pose_data = pose_data
|
| 319 |
+
|
| 320 |
+
# people形式に変換してから保存
|
| 321 |
+
person_data = {
|
| 322 |
+
"pose_keypoints_2d": [],
|
| 323 |
+
"hand_left_keypoints_2d": actual_pose_data.get('hands', [[], []])[0] if actual_pose_data.get('hands') else [],
|
| 324 |
+
"hand_right_keypoints_2d": actual_pose_data.get('hands', [[], []])[1] if actual_pose_data.get('hands') and len(actual_pose_data['hands']) > 1 else [],
|
| 325 |
+
"face_keypoints_2d": actual_pose_data.get('faces', [[]])[0] if actual_pose_data.get('faces') else []
|
| 326 |
+
}
|
| 327 |
+
|
| 328 |
+
# デバッグ:手データの変換確認
|
| 329 |
+
print(f"[DEBUG] 🫳 Hand data conversion:")
|
| 330 |
+
print(f" - hands in data: {bool(actual_pose_data.get('hands'))}")
|
| 331 |
+
print(f" - hands length: {len(actual_pose_data.get('hands', []))}")
|
| 332 |
+
if actual_pose_data.get('hands'):
|
| 333 |
+
print(f" - left hand length: {len(actual_pose_data['hands'][0]) if len(actual_pose_data['hands']) > 0 else 0}")
|
| 334 |
+
print(f" - right hand length: {len(actual_pose_data['hands'][1]) if len(actual_pose_data['hands']) > 1 else 0}")
|
| 335 |
+
print(f" - person_data left hand: {len(person_data['hand_left_keypoints_2d'])}")
|
| 336 |
+
print(f" - person_data right hand: {len(person_data['hand_right_keypoints_2d'])}")
|
| 337 |
+
|
| 338 |
+
# デバッグ:actual_pose_dataの構造確認
|
| 339 |
+
print(f"[DEBUG] 🔍 actual_pose_data structure check:")
|
| 340 |
+
print(f" - keys: {list(actual_pose_data.keys())}")
|
| 341 |
+
print(f" - has bodies: {'bodies' in actual_pose_data}")
|
| 342 |
+
if 'bodies' in actual_pose_data:
|
| 343 |
+
print(f" - bodies keys: {list(actual_pose_data['bodies'].keys())}")
|
| 344 |
+
print(f" - has candidate: {'candidate' in actual_pose_data['bodies']}")
|
| 345 |
+
|
| 346 |
+
# bodies.candidateからpose_keypoints_2d変換
|
| 347 |
+
if 'bodies' in actual_pose_data and 'candidate' in actual_pose_data['bodies']:
|
| 348 |
+
candidates = actual_pose_data['bodies']['candidate']
|
| 349 |
+
print(f"[DEBUG] 🤖 Body data conversion:")
|
| 350 |
+
print(f" - bodies.candidate length: {len(candidates)}")
|
| 351 |
+
for i, candidate in enumerate(candidates):
|
| 352 |
+
if candidate and len(candidate) >= 2:
|
| 353 |
+
person_data["pose_keypoints_2d"].extend([candidate[0], candidate[1], candidate[2] if len(candidate) > 2 else 1.0])
|
| 354 |
+
if i < 3: # 最初の3つだけログ出力
|
| 355 |
+
print(f" - candidate {i}: {candidate[:3]}")
|
| 356 |
+
print(f" - final pose_keypoints_2d length: {len(person_data['pose_keypoints_2d'])}")
|
| 357 |
+
else:
|
| 358 |
+
print(f"[DEBUG] ❌ No bodies.candidate found in actual_pose_data!")
|
| 359 |
+
print(f" - has bodies: {bool(actual_pose_data.get('bodies'))}")
|
| 360 |
+
if actual_pose_data.get('bodies'):
|
| 361 |
+
print(f" - bodies keys: {list(actual_pose_data['bodies'].keys())}")
|
| 362 |
|
| 363 |
+
_current_poses = [{
|
| 364 |
+
'people': [person_data],
|
| 365 |
+
'metadata': {
|
| 366 |
+
'resolution': actual_pose_data.get('resolution', [512, 512])
|
|
|
|
|
|
|
|
|
|
|
|
|
| 367 |
}
|
| 368 |
+
}]
|
| 369 |
+
_current_frame_index = 0
|
| 370 |
+
print(f"[DEBUG] ✅ グローバル変数更新完了(テンプレート読み込み・refs互換): {template_name}")
|
| 371 |
+
|
| 372 |
+
# people形式でデータを構築(元のbodies/hands/facesも保持)
|
| 373 |
+
people_format_data = {
|
| 374 |
+
'people': [person_data],
|
| 375 |
+
'bodies': actual_pose_data.get('bodies', {}), # 元のbodiesデータも保持
|
| 376 |
+
'hands': actual_pose_data.get('hands', []), # 元のhandsデータも保持
|
| 377 |
+
'faces': actual_pose_data.get('faces', []), # 元のfacesデータも保持
|
| 378 |
+
'metadata': {
|
| 379 |
+
'resolution': actual_pose_data.get('resolution', [512, 512])
|
| 380 |
+
},
|
| 381 |
+
'is_template_load': True # テンプレート読み込みフラグ
|
| 382 |
+
}
|
| 383 |
+
|
| 384 |
+
print(f"[DEBUG] 🔄 Returning people format data with {len(person_data['hand_left_keypoints_2d'])} left hand points")
|
| 385 |
|
| 386 |
notify_success(f"{template_name}を読み込みました")
|
| 387 |
+
return people_format_data, people_format_data
|
| 388 |
else:
|
| 389 |
notify_error("テンプレートが見つかりません")
|
| 390 |
return None, {}
|
|
|
|
| 814 |
outputs=[js_executor]
|
| 815 |
)
|
| 816 |
|
| 817 |
+
# ポーズ更新ボタンクリックイベント
|
| 818 |
+
template_update_btn.click(
|
| 819 |
fn=load_template_pose,
|
| 820 |
inputs=[template_dropdown],
|
| 821 |
outputs=[output_json, pose_data]
|
issues/039_テンプレート選択機能改善.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Issue #039: テンプレート選択機能改善 🎯✨
|
| 2 |
+
|
| 3 |
+
## 概要
|
| 4 |
+
現在のテンプレートドロップダウンには3つのテンプレートが登録されているが、これを1つに集約し、「ポーズ更新」ボタンを追加してユーザーが任意のタイミングでテンプレートを反映できる機能を実装する。
|
| 5 |
+
|
| 6 |
+
## 問題の詳細
|
| 7 |
+
|
| 8 |
+
### 現在の状況
|
| 9 |
+
- テンプレートドロップダウンに3つのテンプレートが登録済み
|
| 10 |
+
- "2頭身立ちポーズ"
|
| 11 |
+
- "3頭身立ちポーズ"
|
| 12 |
+
- "2頭身座りポーズ"
|
| 13 |
+
- 3heads.jsonに3頭身テンプレートデータが用意済み
|
| 14 |
+
- テンプレート選択時に自動反映される仕様
|
| 15 |
+
|
| 16 |
+
### 改善したい点
|
| 17 |
+
1. **テンプレート数の集約**: 現在の3つから1つに削減
|
| 18 |
+
2. **手動更新方式**: 自動反映ではなく、「ポーズ更新」ボタンによる手動更新
|
| 19 |
+
3. **テンプレートファイル活用**: 3heads.jsonの活用
|
| 20 |
+
|
| 21 |
+
## 解決方法
|
| 22 |
+
|
| 23 |
+
### 1. テンプレートリストの変更
|
| 24 |
+
```python
|
| 25 |
+
# Before
|
| 26 |
+
template_dropdown = gr.Dropdown(
|
| 27 |
+
label="テンプレートポーズ",
|
| 28 |
+
choices=[
|
| 29 |
+
"2頭身立ちポーズ",
|
| 30 |
+
"3頭身立ちポーズ",
|
| 31 |
+
"2頭身座りポーズ"
|
| 32 |
+
],
|
| 33 |
+
value="2頭身立ちポーズ"
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
+
# After
|
| 37 |
+
template_dropdown = gr.Dropdown(
|
| 38 |
+
label="テンプレートポーズ",
|
| 39 |
+
choices=["3頭身立ちポーズ"],
|
| 40 |
+
value="3頭身立ちポーズ"
|
| 41 |
+
)
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
### 2. ポーズ更新ボタンの追加
|
| 45 |
+
テンプレートドロップダウンの直下に「ポーズ更新」ボタンを配置:
|
| 46 |
+
```python
|
| 47 |
+
template_update_btn = gr.Button(
|
| 48 |
+
"🔄 ポーズ更新",
|
| 49 |
+
variant="secondary",
|
| 50 |
+
scale=0
|
| 51 |
+
)
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
### 3. イベントハンドラーの変更
|
| 55 |
+
- 既存の `template_dropdown.change` イベントを削除
|
| 56 |
+
- 新しい `template_update_btn.click` イベントを追加
|
| 57 |
+
|
| 58 |
+
### 4. テンプレートファイルの統合
|
| 59 |
+
- 3heads.jsonを適切に読み込む処理を実装
|
| 60 |
+
- テンプレート名とファイルパスのマッピングを更新
|
| 61 |
+
|
| 62 |
+
## 実装詳細
|
| 63 |
+
|
| 64 |
+
### Phase 1: UIコンポーネントの変更
|
| 65 |
+
1. `app.py:70-78` テンプレートドロップダウンの選択肢を1つに変更
|
| 66 |
+
2. `app.py:78` の直後に「ポーズ更新」ボタンを追加
|
| 67 |
+
|
| 68 |
+
### Phase 2: イベントハンドラーの変更
|
| 69 |
+
1. `app.py:758-761` 既存のテンプレート自動更新イベントを削除
|
| 70 |
+
2. 新しいボタンクリックイベントを追加
|
| 71 |
+
3. `on_template_load()` 関数は既存のものを流用
|
| 72 |
+
|
| 73 |
+
### Phase 3: テンプレートファイル処理の修正
|
| 74 |
+
1. 3heads.jsonの読み込み処理を確認
|
| 75 |
+
2. テンプレート名とファイルパスのマッピングを更新
|
| 76 |
+
3. "3頭身立ちポーズ" → `3heads.json` の対応付け
|
| 77 |
+
|
| 78 |
+
## 期待される効果
|
| 79 |
+
|
| 80 |
+
### ユーザーエクスペリエンス
|
| 81 |
+
- **シンプルな選択肢**: 1つのテンプレートで迷わない
|
| 82 |
+
- **手動制御**: ユーザーが任意のタイミングで更新可能
|
| 83 |
+
- **明確な操作**: ボタンクリックで何が起こるかが明確
|
| 84 |
+
|
| 85 |
+
### 技術的メリット
|
| 86 |
+
- **コード簡素化**: テンプレート管理が単純化
|
| 87 |
+
- **ファイル活用**: 実際のテンプレートファイルを有効活用
|
| 88 |
+
- **デバッグ容易性**: 手動トリガーでデバッグしやすい
|
| 89 |
+
|
| 90 |
+
## テスト項目
|
| 91 |
+
|
| 92 |
+
### 基本機能テスト
|
| 93 |
+
- [ ] テンプレートドロップダウンに「3頭身立ちポーズ」のみ表示
|
| 94 |
+
- [ ] 「ポーズ更新」ボタンが正常に表示される
|
| 95 |
+
- [ ] ボタンクリックで3heads.jsonのポーズデータが読み込まれる
|
| 96 |
+
- [ ] Canvas上にポーズが正常に描画される
|
| 97 |
+
|
| 98 |
+
### エラーハンドリング
|
| 99 |
+
- [ ] 3heads.jsonが存在しない場合のエラー処理
|
| 100 |
+
- [ ] JSONファイルが不正な場合のエラー処理
|
| 101 |
+
- [ ] Canvas更新失敗時のエラー処理
|
| 102 |
+
|
| 103 |
+
### UI/UX確認
|
| 104 |
+
- [ ] ボタンの配置とデザインが適切
|
| 105 |
+
- [ ] トースト通知が正常に表示される
|
| 106 |
+
- [ ] レスポンシブデザインの確認
|
| 107 |
+
|
| 108 |
+
## 参考実装
|
| 109 |
+
|
| 110 |
+
### refs/dwpose_modifier参照点
|
| 111 |
+
- `refs/dwpose_modifier/app.py` テンプレート選択UI実装
|
| 112 |
+
- `refs/dwpose_modifier/static/pose_editor.js` Canvas更新処理
|
| 113 |
+
- `refs/dwpose_modifier/utils/template_loader.py` テンプレート読み込み処理
|
| 114 |
+
|
| 115 |
+
### 既存コード活用
|
| 116 |
+
- `on_template_load()` 関数 (app.py:281)
|
| 117 |
+
- `update_canvas_with_pose()` 処理
|
| 118 |
+
- エラーハンドリング (`utils/notifications.py`)
|
| 119 |
+
|
| 120 |
+
## 実装工数
|
| 121 |
+
- **見積もり**: 2-3時間
|
| 122 |
+
- **優先度**: Medium
|
| 123 |
+
- **複雑度**: Low-Medium
|
| 124 |
+
|
| 125 |
+
## 完了条件
|
| 126 |
+
1. テンプレートドロップダウンが1つの選択肢のみ表示される
|
| 127 |
+
2. 「ポーズ更新」ボタンが適切に配置・動作する
|
| 128 |
+
3. 3heads.jsonのテンプレートデータが正常に読み込まれる
|
| 129 |
+
4. Canvas上にポーズが正確に描画される
|
| 130 |
+
5. エラーハンドリングが適切に動作する
|
| 131 |
+
|
| 132 |
+
---
|
| 133 |
+
*Created: 2025-01-15*
|
| 134 |
+
*Status: 新規作成*
|
| 135 |
+
*Assignee: Claude Code Agent*
|
| 136 |
+
*Tags: UI改善, テンプ��ート機能, ユーザビリティ*
|
static/pose_editor.js
CHANGED
|
@@ -1876,14 +1876,23 @@ function drawPose(poseData, enableHands = true, enableFace = true, highlightInde
|
|
| 1876 |
person.hand_left_keypoints_2d || [],
|
| 1877 |
person.hand_right_keypoints_2d || []
|
| 1878 |
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1879 |
// 💖 people形式のみサポート、古いhands形式は削除
|
| 1880 |
} else {
|
| 1881 |
handsDataForDrawing = [[], []]; // 空の手データ
|
|
|
|
| 1882 |
}
|
| 1883 |
|
| 1884 |
if (handsDataForDrawing && handsDataForDrawing.length >= 2) {
|
| 1885 |
drawHands(handsDataForDrawing, originalRes, scaleX, scaleY);
|
| 1886 |
debugLog(`🫳 Hands drawn: left=${handsDataForDrawing[0].length}, right=${handsDataForDrawing[1].length}`);
|
|
|
|
|
|
|
| 1887 |
}
|
| 1888 |
} catch (error) {
|
| 1889 |
console.error("❌ Error drawing hands:", error);
|
|
@@ -2363,9 +2372,20 @@ window.gradioCanvasUpdate = function(pose_json_str) {
|
|
| 2363 |
hasBodies: !!poseData?.bodies,
|
| 2364 |
hasHands: !!poseData?.hands,
|
| 2365 |
hasFaces: !!poseData?.faces,
|
| 2366 |
-
hasBackgroundImage: !!poseData?.background_image
|
|
|
|
|
|
|
|
|
|
| 2367 |
});
|
| 2368 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2369 |
// 🎨 背景画像が含まれている場合は設定
|
| 2370 |
if (poseData && poseData.background_image) {
|
| 2371 |
if (window.setBackgroundImage) {
|
|
@@ -2373,9 +2393,28 @@ window.gradioCanvasUpdate = function(pose_json_str) {
|
|
| 2373 |
}
|
| 2374 |
}
|
| 2375 |
|
| 2376 |
-
// 💥
|
|
|
|
| 2377 |
const existingPoseData = window.poseEditorGlobals.poseData;
|
| 2378 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2379 |
poseData && (!poseData.people || !poseData.people[0])) {
|
| 2380 |
|
| 2381 |
console.log('🛡️ [gradioCanvasUpdate] Protecting existing people data from overwrite');
|
|
@@ -2461,6 +2500,14 @@ window.gradioCanvasUpdate = function(pose_json_str) {
|
|
| 2461 |
|
| 2462 |
// 🔧 グローバル設定で描画(手・顔表示設定を反映)
|
| 2463 |
if (poseData && Object.keys(poseData).length > 0) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2464 |
drawPose(
|
| 2465 |
poseData,
|
| 2466 |
window.poseEditorGlobals.enableHands,
|
|
|
|
| 1876 |
person.hand_left_keypoints_2d || [],
|
| 1877 |
person.hand_right_keypoints_2d || []
|
| 1878 |
];
|
| 1879 |
+
console.log('🫳 [HANDS DEBUG] Hand data prepared:', {
|
| 1880 |
+
leftLength: handsDataForDrawing[0].length,
|
| 1881 |
+
rightLength: handsDataForDrawing[1].length,
|
| 1882 |
+
leftSample: handsDataForDrawing[0].slice(0, 9),
|
| 1883 |
+
rightSample: handsDataForDrawing[1].slice(0, 9)
|
| 1884 |
+
});
|
| 1885 |
// 💖 people形式のみサポート、古いhands形式は削除
|
| 1886 |
} else {
|
| 1887 |
handsDataForDrawing = [[], []]; // 空の手データ
|
| 1888 |
+
console.log('🫳 [HANDS DEBUG] No people data, using empty hands');
|
| 1889 |
}
|
| 1890 |
|
| 1891 |
if (handsDataForDrawing && handsDataForDrawing.length >= 2) {
|
| 1892 |
drawHands(handsDataForDrawing, originalRes, scaleX, scaleY);
|
| 1893 |
debugLog(`🫳 Hands drawn: left=${handsDataForDrawing[0].length}, right=${handsDataForDrawing[1].length}`);
|
| 1894 |
+
} else {
|
| 1895 |
+
console.log('🫳 [HANDS DEBUG] Invalid handsDataForDrawing structure');
|
| 1896 |
}
|
| 1897 |
} catch (error) {
|
| 1898 |
console.error("❌ Error drawing hands:", error);
|
|
|
|
| 2372 |
hasBodies: !!poseData?.bodies,
|
| 2373 |
hasHands: !!poseData?.hands,
|
| 2374 |
hasFaces: !!poseData?.faces,
|
| 2375 |
+
hasBackgroundImage: !!poseData?.background_image,
|
| 2376 |
+
handLeftLength: poseData?.people?.[0]?.hand_left_keypoints_2d?.length || 0,
|
| 2377 |
+
handRightLength: poseData?.people?.[0]?.hand_right_keypoints_2d?.length || 0,
|
| 2378 |
+
isTemplateLoad: !!poseData?.is_template_load
|
| 2379 |
});
|
| 2380 |
|
| 2381 |
+
// 🔍 テンプレート読み込み時の詳細ログ
|
| 2382 |
+
if (poseData?.is_template_load) {
|
| 2383 |
+
console.log('🔄 [TEMPLATE LOAD] Detailed hand data check:', {
|
| 2384 |
+
leftHandData: poseData?.people?.[0]?.hand_left_keypoints_2d?.slice(0, 9) || 'NO DATA',
|
| 2385 |
+
rightHandData: poseData?.people?.[0]?.hand_right_keypoints_2d?.slice(0, 9) || 'NO DATA'
|
| 2386 |
+
});
|
| 2387 |
+
}
|
| 2388 |
+
|
| 2389 |
// 🎨 背景画像が含まれている場合は設定
|
| 2390 |
if (poseData && poseData.background_image) {
|
| 2391 |
if (window.setBackgroundImage) {
|
|
|
|
| 2393 |
}
|
| 2394 |
}
|
| 2395 |
|
| 2396 |
+
// 💥 テンプレート読み込み時は完全置換、それ以外は既存データ保護
|
| 2397 |
+
const isTemplateLoad = poseData.is_template_load === true;
|
| 2398 |
const existingPoseData = window.poseEditorGlobals.poseData;
|
| 2399 |
+
|
| 2400 |
+
if (isTemplateLoad) {
|
| 2401 |
+
console.log('🔄 [gradioCanvasUpdate] Template load detected - complete replacement');
|
| 2402 |
+
// テンプレート読み込み時は完全置換
|
| 2403 |
+
window.poseEditorGlobals.poseData = poseData;
|
| 2404 |
+
// baseOriginalKeypointsもリセット(新しいテンプレート用)
|
| 2405 |
+
window.poseEditorGlobals.baseOriginalKeypoints = null;
|
| 2406 |
+
|
| 2407 |
+
// 🔧 テンプレート読み込み時は現在のチェックボックス状態を強制取得
|
| 2408 |
+
updateDisplaySettingsFromCheckbox();
|
| 2409 |
+
console.log('🔧 [TEMPLATE LOAD] Forced display settings update:', {
|
| 2410 |
+
enableHands: window.poseEditorGlobals.enableHands,
|
| 2411 |
+
enableFace: window.poseEditorGlobals.enableFace,
|
| 2412 |
+
editMode: window.poseEditorGlobals.editMode
|
| 2413 |
+
});
|
| 2414 |
+
|
| 2415 |
+
// 念のため、チェックボックス監視も再設定
|
| 2416 |
+
setTimeout(() => setupGradioCheckboxListeners(), 100);
|
| 2417 |
+
} else if (existingPoseData && existingPoseData.people && existingPoseData.people[0] &&
|
| 2418 |
poseData && (!poseData.people || !poseData.people[0])) {
|
| 2419 |
|
| 2420 |
console.log('🛡️ [gradioCanvasUpdate] Protecting existing people data from overwrite');
|
|
|
|
| 2500 |
|
| 2501 |
// 🔧 グローバル設定で描画(手・顔表示設定を反映)
|
| 2502 |
if (poseData && Object.keys(poseData).length > 0) {
|
| 2503 |
+
console.log('🎨 [DRAW CALL] About to call drawPose with settings:', {
|
| 2504 |
+
enableHands: window.poseEditorGlobals.enableHands,
|
| 2505 |
+
enableFace: window.poseEditorGlobals.enableFace,
|
| 2506 |
+
editMode: window.poseEditorGlobals.editMode,
|
| 2507 |
+
hasPeopleData: !!poseData.people,
|
| 2508 |
+
handDataAvailable: !!(poseData.people?.[0]?.hand_left_keypoints_2d?.length > 0)
|
| 2509 |
+
});
|
| 2510 |
+
|
| 2511 |
drawPose(
|
| 2512 |
poseData,
|
| 2513 |
window.poseEditorGlobals.enableHands,
|
templates/poses.json
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"poses": {
|
| 3 |
+
"2_head_standing": {
|
| 4 |
+
"name": "2頭身立ちポーズ",
|
| 5 |
+
"description": "2頭身キャラクター用基本立ちポーズ",
|
| 6 |
+
"data": {
|
| 7 |
+
"bodies": {
|
| 8 |
+
"candidate": [
|
| 9 |
+
[320, 100], [300, 120], [280, 140], [260, 160], [240, 180],
|
| 10 |
+
[340, 120], [360, 140], [380, 160], [400, 180],
|
| 11 |
+
[310, 200], [305, 250], [300, 300],
|
| 12 |
+
[330, 200], [335, 250], [340, 300],
|
| 13 |
+
[320, 80], [320, 60]
|
| 14 |
+
],
|
| 15 |
+
"subset": [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1.0, 17]]
|
| 16 |
+
},
|
| 17 |
+
"hands": [
|
| 18 |
+
[280, 160, 1.0, 285, 165, 1.0, 290, 170, 1.0, 295, 175, 1.0, 300, 180, 1.0,
|
| 19 |
+
275, 170, 1.0, 280, 175, 1.0, 285, 180, 1.0, 290, 185, 1.0,
|
| 20 |
+
270, 175, 1.0, 275, 180, 1.0, 280, 185, 1.0, 285, 190, 1.0,
|
| 21 |
+
265, 180, 1.0, 270, 185, 1.0, 275, 190, 1.0, 280, 195, 1.0,
|
| 22 |
+
260, 185, 1.0, 265, 190, 1.0, 270, 195, 1.0],
|
| 23 |
+
[380, 160, 1.0, 375, 165, 1.0, 370, 170, 1.0, 365, 175, 1.0, 360, 180, 1.0,
|
| 24 |
+
385, 170, 1.0, 380, 175, 1.0, 375, 180, 1.0, 370, 185, 1.0,
|
| 25 |
+
390, 175, 1.0, 385, 180, 1.0, 380, 185, 1.0, 375, 190, 1.0,
|
| 26 |
+
395, 180, 1.0, 390, 185, 1.0, 385, 190, 1.0, 380, 195, 1.0,
|
| 27 |
+
400, 185, 1.0, 395, 190, 1.0, 390, 195, 1.0]
|
| 28 |
+
],
|
| 29 |
+
"faces": [
|
| 30 |
+
[320, 60, 1.0, 315, 65, 1.0, 310, 70, 1.0, 315, 75, 1.0, 320, 80, 1.0,
|
| 31 |
+
325, 75, 1.0, 330, 70, 1.0, 325, 65, 1.0, 320, 70, 1.0, 318, 72, 1.0,
|
| 32 |
+
322, 72, 1.0, 320, 75, 1.0, 315, 80, 1.0, 320, 85, 1.0, 325, 80, 1.0,
|
| 33 |
+
310, 85, 1.0, 315, 90, 1.0, 320, 95, 1.0, 325, 90, 1.0, 330, 85, 1.0]
|
| 34 |
+
],
|
| 35 |
+
"resolution": [640, 640]
|
| 36 |
+
}
|
| 37 |
+
},
|
| 38 |
+
"3_head_standing": {
|
| 39 |
+
"name": "3頭身立ちポーズ",
|
| 40 |
+
"description": "3頭身キャラクター用基本立ちポーズ",
|
| 41 |
+
"data": {
|
| 42 |
+
"bodies": {
|
| 43 |
+
"candidate": [
|
| 44 |
+
[320, 120], [300, 140], [280, 160], [260, 180], [240, 200],
|
| 45 |
+
[340, 140], [360, 160], [380, 180], [400, 200],
|
| 46 |
+
[310, 250], [305, 350], [300, 450],
|
| 47 |
+
[330, 250], [335, 350], [340, 450],
|
| 48 |
+
[320, 100], [320, 80]
|
| 49 |
+
],
|
| 50 |
+
"subset": [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1.0, 17]]
|
| 51 |
+
},
|
| 52 |
+
"hands": [
|
| 53 |
+
[280, 160, 1.0, 285, 165, 1.0, 290, 170, 1.0, 295, 175, 1.0, 300, 180, 1.0,
|
| 54 |
+
275, 170, 1.0, 280, 175, 1.0, 285, 180, 1.0, 290, 185, 1.0,
|
| 55 |
+
270, 175, 1.0, 275, 180, 1.0, 280, 185, 1.0, 285, 190, 1.0,
|
| 56 |
+
265, 180, 1.0, 270, 185, 1.0, 275, 190, 1.0, 280, 195, 1.0,
|
| 57 |
+
260, 185, 1.0, 265, 190, 1.0, 270, 195, 1.0],
|
| 58 |
+
[380, 160, 1.0, 375, 165, 1.0, 370, 170, 1.0, 365, 175, 1.0, 360, 180, 1.0,
|
| 59 |
+
385, 170, 1.0, 380, 175, 1.0, 375, 180, 1.0, 370, 185, 1.0,
|
| 60 |
+
390, 175, 1.0, 385, 180, 1.0, 380, 185, 1.0, 375, 190, 1.0,
|
| 61 |
+
395, 180, 1.0, 390, 185, 1.0, 385, 190, 1.0, 380, 195, 1.0,
|
| 62 |
+
400, 185, 1.0, 395, 190, 1.0, 390, 195, 1.0]
|
| 63 |
+
],
|
| 64 |
+
"faces": [
|
| 65 |
+
[320, 60, 1.0, 315, 65, 1.0, 310, 70, 1.0, 315, 75, 1.0, 320, 80, 1.0,
|
| 66 |
+
325, 75, 1.0, 330, 70, 1.0, 325, 65, 1.0, 320, 70, 1.0, 318, 72, 1.0,
|
| 67 |
+
322, 72, 1.0, 320, 75, 1.0, 315, 80, 1.0, 320, 85, 1.0, 325, 80, 1.0,
|
| 68 |
+
310, 85, 1.0, 315, 90, 1.0, 320, 95, 1.0, 325, 90, 1.0, 330, 85, 1.0]
|
| 69 |
+
],
|
| 70 |
+
"resolution": [640, 640]
|
| 71 |
+
}
|
| 72 |
+
},
|
| 73 |
+
"2_head_sitting": {
|
| 74 |
+
"name": "2頭身座りポーズ",
|
| 75 |
+
"description": "2頭身キャラクター用座りポーズ",
|
| 76 |
+
"data": {
|
| 77 |
+
"bodies": {
|
| 78 |
+
"candidate": [
|
| 79 |
+
[320, 150], [300, 170], [280, 190], [260, 210], [240, 230],
|
| 80 |
+
[340, 170], [360, 190], [380, 210], [400, 230],
|
| 81 |
+
[310, 220], [290, 250], [270, 280],
|
| 82 |
+
[330, 220], [350, 250], [370, 280],
|
| 83 |
+
[320, 130], [320, 110]
|
| 84 |
+
],
|
| 85 |
+
"subset": [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1.0, 17]]
|
| 86 |
+
},
|
| 87 |
+
"hands": [
|
| 88 |
+
[280, 160, 1.0, 285, 165, 1.0, 290, 170, 1.0, 295, 175, 1.0, 300, 180, 1.0,
|
| 89 |
+
275, 170, 1.0, 280, 175, 1.0, 285, 180, 1.0, 290, 185, 1.0,
|
| 90 |
+
270, 175, 1.0, 275, 180, 1.0, 280, 185, 1.0, 285, 190, 1.0,
|
| 91 |
+
265, 180, 1.0, 270, 185, 1.0, 275, 190, 1.0, 280, 195, 1.0,
|
| 92 |
+
260, 185, 1.0, 265, 190, 1.0, 270, 195, 1.0],
|
| 93 |
+
[380, 160, 1.0, 375, 165, 1.0, 370, 170, 1.0, 365, 175, 1.0, 360, 180, 1.0,
|
| 94 |
+
385, 170, 1.0, 380, 175, 1.0, 375, 180, 1.0, 370, 185, 1.0,
|
| 95 |
+
390, 175, 1.0, 385, 180, 1.0, 380, 185, 1.0, 375, 190, 1.0,
|
| 96 |
+
395, 180, 1.0, 390, 185, 1.0, 385, 190, 1.0, 380, 195, 1.0,
|
| 97 |
+
400, 185, 1.0, 395, 190, 1.0, 390, 195, 1.0]
|
| 98 |
+
],
|
| 99 |
+
"faces": [
|
| 100 |
+
[320, 60, 1.0, 315, 65, 1.0, 310, 70, 1.0, 315, 75, 1.0, 320, 80, 1.0,
|
| 101 |
+
325, 75, 1.0, 330, 70, 1.0, 325, 65, 1.0, 320, 70, 1.0, 318, 72, 1.0,
|
| 102 |
+
322, 72, 1.0, 320, 75, 1.0, 315, 80, 1.0, 320, 85, 1.0, 325, 80, 1.0,
|
| 103 |
+
310, 85, 1.0, 315, 90, 1.0, 320, 95, 1.0, 325, 90, 1.0, 330, 85, 1.0]
|
| 104 |
+
],
|
| 105 |
+
"resolution": [640, 640]
|
| 106 |
+
}
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
}
|