Spaces:
Runtime error
Runtime error
add new rotation method
Browse files- app.py +4 -4
- static/poseEditor.js +57 -17
app.py
CHANGED
@@ -83,8 +83,8 @@ with gr.Blocks() as demo:
|
|
83 |
with gr.Row():
|
84 |
with gr.Column(scale=1):
|
85 |
startBtn = gr.Button(value="Start edit")
|
86 |
-
width = gr.Slider(label="Width",
|
87 |
-
height = gr.Slider(label="Height",
|
88 |
with gr.Accordion(label="Pose estimation", open=False):
|
89 |
source = gr.Image(type="pil")
|
90 |
gr.Markdown("""push "Start edit" after estimation done.""")
|
@@ -107,9 +107,9 @@ with gr.Blocks() as demo:
|
|
107 |
gr.Markdown("""
|
108 |
- "ctrl + drag" to scale
|
109 |
- "alt + drag" to translate
|
110 |
-
- "shift + drag" to rotate(move right first, then up or down)
|
111 |
- "space + drag" to move within range
|
112 |
-
- "[", "]" to shrink or expand range
|
113 |
""")
|
114 |
|
115 |
source.change(
|
|
|
83 |
with gr.Row():
|
84 |
with gr.Column(scale=1):
|
85 |
startBtn = gr.Button(value="Start edit")
|
86 |
+
width = gr.Slider(label="Width", minimum=512, maximum=1024, step=64, value=512, interactive=True)
|
87 |
+
height = gr.Slider(label="Height", minimum=512, maximum=1024, step=64, value=512, interactive=True)
|
88 |
with gr.Accordion(label="Pose estimation", open=False):
|
89 |
source = gr.Image(type="pil")
|
90 |
gr.Markdown("""push "Start edit" after estimation done.""")
|
|
|
107 |
gr.Markdown("""
|
108 |
- "ctrl + drag" to scale
|
109 |
- "alt + drag" to translate
|
110 |
+
- "shift + drag" to rotate(move right first, release shift, then up or down)
|
111 |
- "space + drag" to move within range
|
112 |
+
- "[", "]" or mouse wheel to shrink or expand range
|
113 |
""")
|
114 |
|
115 |
source.change(
|
static/poseEditor.js
CHANGED
@@ -37,6 +37,10 @@ var keyDownFlags = {};
|
|
37 |
// マウスカーソル
|
38 |
var mouseCursor = [0, 0];
|
39 |
|
|
|
|
|
|
|
|
|
40 |
function clearCanvas() {
|
41 |
var w = canvas.width;
|
42 |
var h = canvas.height;
|
@@ -110,6 +114,15 @@ function drawUI() {
|
|
110 |
ctx.strokeStyle = 'rgb(255,255,255)';
|
111 |
ctx.stroke();
|
112 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
}
|
114 |
|
115 |
function Redraw() {
|
@@ -142,6 +155,8 @@ let dragStartY = 0;
|
|
142 |
let draggingCandidate = null;
|
143 |
let dragPersonIndex = -1;
|
144 |
let dragMarks = [];
|
|
|
|
|
145 |
|
146 |
function getCanvasPosition(event) {
|
147 |
const rect = canvas.getBoundingClientRect();
|
@@ -191,11 +206,20 @@ function handleMouseDown(event) {
|
|
191 |
}
|
192 |
}
|
193 |
|
194 |
-
if (event.altKey || event.ctrlKey || event.
|
195 |
forEachCandidateOfPerson(dragPersonIndex, (i) => {
|
196 |
dragMarks[i] = true;
|
197 |
});
|
198 |
isDragging = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
} else if (keyDownFlags["Space"]) {
|
200 |
var markCount = 0;
|
201 |
forEachCandidateOfPerson(dragPersonIndex, (i) => {
|
@@ -207,9 +231,11 @@ function handleMouseDown(event) {
|
|
207 |
}
|
208 |
});
|
209 |
isDragging = 0 < markCount;
|
|
|
210 |
} else if (minDist < 16) {
|
211 |
dragMarks[index] = true;
|
212 |
isDragging = true;
|
|
|
213 |
}
|
214 |
}
|
215 |
|
@@ -222,31 +248,32 @@ function handleMouseMove(event) {
|
|
222 |
const dragOffsetX = x - dragStartX;
|
223 |
const dragOffsetY = y - dragStartY;
|
224 |
|
225 |
-
if (
|
226 |
-
//
|
227 |
let xScale = 1 + dragOffsetX / canvas.width;
|
228 |
let yScale = 1 + dragOffsetY / canvas.height;
|
229 |
forEachMarkedCandidate((index) => {
|
230 |
candidate[index][0] = (draggingCandidate[index][0] - dragStartX) * xScale + dragStartX;
|
231 |
candidate[index][1] = (draggingCandidate[index][1] - dragStartY) * yScale + dragStartY;
|
232 |
});
|
233 |
-
} else if (
|
234 |
-
|
235 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
forEachMarkedCandidate((index) => {
|
237 |
let x = draggingCandidate[index][0] - dragStartX;
|
238 |
let y = draggingCandidate[index][1] - dragStartY;
|
239 |
candidate[index][0] = x * Math.cos(angle) - y * Math.sin(angle) + dragStartX;
|
240 |
candidate[index][1] = x * Math.sin(angle) + y * Math.cos(angle) + dragStartY;
|
241 |
});
|
242 |
-
} else if (
|
243 |
-
//
|
244 |
-
forEachCandidateOfPerson(dragPersonIndex, (index) => {
|
245 |
-
candidate[index][0] = draggingCandidate[index][0] + dragOffsetX;
|
246 |
-
candidate[index][1] = draggingCandidate[index][1] + dragOffsetY;
|
247 |
-
});
|
248 |
-
} else {
|
249 |
-
// 個別移動
|
250 |
forEachMarkedCandidate((index) => {
|
251 |
if (dragMarks[index]) {
|
252 |
candidate[index][0] = draggingCandidate[index][0] + dragOffsetX;
|
@@ -259,11 +286,24 @@ function handleMouseMove(event) {
|
|
259 |
Redraw();
|
260 |
}
|
261 |
|
262 |
-
function handleMouseUp(event) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
263 |
|
264 |
document.addEventListener("keydown", (event) => {
|
265 |
-
if (event.code == "BracketLeft") {
|
266 |
-
if (event.code == "BracketRight") {
|
267 |
keyDownFlags[event.code] = true;
|
268 |
Redraw();
|
269 |
});
|
|
|
37 |
// マウスカーソル
|
38 |
var mouseCursor = [0, 0];
|
39 |
|
40 |
+
function cross(lhs, rhs) {return lhs[0] * rhs[1] - lhs[1] * rhs[0];}
|
41 |
+
function dot(lhs, rhs) {return lhs[0] * rhs[0] + lhs[1] * rhs[1];}
|
42 |
+
function directedAngleTo(lhs, rhs) {return Math.atan2(cross(lhs, rhs), dot(lhs, rhs));}
|
43 |
+
|
44 |
function clearCanvas() {
|
45 |
var w = canvas.width;
|
46 |
var h = canvas.height;
|
|
|
114 |
ctx.strokeStyle = 'rgb(255,255,255)';
|
115 |
ctx.stroke();
|
116 |
}
|
117 |
+
|
118 |
+
if (isDragging && (dragMode == "rotate" || dragMode == "rotate2")) {
|
119 |
+
ctx.beginPath();
|
120 |
+
ctx.lineWidth=1;
|
121 |
+
ctx.strokeStyle = 'rgb(255,255,255)';
|
122 |
+
ctx.moveTo(dragStartX, dragStartY);
|
123 |
+
ctx.lineTo(dragStartX+rotateBaseVector[0], dragStartY+rotateBaseVector[1]);
|
124 |
+
ctx.stroke();
|
125 |
+
}
|
126 |
}
|
127 |
|
128 |
function Redraw() {
|
|
|
155 |
let draggingCandidate = null;
|
156 |
let dragPersonIndex = -1;
|
157 |
let dragMarks = [];
|
158 |
+
let dragMode = "";
|
159 |
+
let rotateBaseVector = null;
|
160 |
|
161 |
function getCanvasPosition(event) {
|
162 |
const rect = canvas.getBoundingClientRect();
|
|
|
206 |
}
|
207 |
}
|
208 |
|
209 |
+
if (event.altKey || event.ctrlKey || event.shiftKey) {
|
210 |
forEachCandidateOfPerson(dragPersonIndex, (i) => {
|
211 |
dragMarks[i] = true;
|
212 |
});
|
213 |
isDragging = true;
|
214 |
+
if (event.altKey) {
|
215 |
+
dragMode = "move";
|
216 |
+
} else if (event.ctrlKey) {
|
217 |
+
dragMode = "scale";
|
218 |
+
} else if (event.shiftKey) {
|
219 |
+
dragMode = "rotate";
|
220 |
+
rotateBaseVector = [0, 0];
|
221 |
+
}
|
222 |
+
console.log(dragMode);
|
223 |
} else if (keyDownFlags["Space"]) {
|
224 |
var markCount = 0;
|
225 |
forEachCandidateOfPerson(dragPersonIndex, (i) => {
|
|
|
231 |
}
|
232 |
});
|
233 |
isDragging = 0 < markCount;
|
234 |
+
dragMode = "move";
|
235 |
} else if (minDist < 16) {
|
236 |
dragMarks[index] = true;
|
237 |
isDragging = true;
|
238 |
+
dragMode = "move";
|
239 |
}
|
240 |
}
|
241 |
|
|
|
248 |
const dragOffsetX = x - dragStartX;
|
249 |
const dragOffsetY = y - dragStartY;
|
250 |
|
251 |
+
if (dragMode == "scale") {
|
252 |
+
// 拡大縮小
|
253 |
let xScale = 1 + dragOffsetX / canvas.width;
|
254 |
let yScale = 1 + dragOffsetY / canvas.height;
|
255 |
forEachMarkedCandidate((index) => {
|
256 |
candidate[index][0] = (draggingCandidate[index][0] - dragStartX) * xScale + dragStartX;
|
257 |
candidate[index][1] = (draggingCandidate[index][1] - dragStartY) * yScale + dragStartY;
|
258 |
});
|
259 |
+
} else if (dragMode == "rotate") {
|
260 |
+
rotateBaseVector = [dragOffsetX, dragOffsetY];
|
261 |
+
if (!event.shiftKey) {
|
262 |
+
dragMode = "rotate2";
|
263 |
+
console.log("rotate2");
|
264 |
+
}
|
265 |
+
console.log("!");
|
266 |
+
} else if (dragMode == "rotate2") {
|
267 |
+
// 回転
|
268 |
+
let angle = directedAngleTo(rotateBaseVector, [dragOffsetX, dragOffsetY]);
|
269 |
forEachMarkedCandidate((index) => {
|
270 |
let x = draggingCandidate[index][0] - dragStartX;
|
271 |
let y = draggingCandidate[index][1] - dragStartY;
|
272 |
candidate[index][0] = x * Math.cos(angle) - y * Math.sin(angle) + dragStartX;
|
273 |
candidate[index][1] = x * Math.sin(angle) + y * Math.cos(angle) + dragStartY;
|
274 |
});
|
275 |
+
} else if (dragMode == "move") {
|
276 |
+
// 移動
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
forEachMarkedCandidate((index) => {
|
278 |
if (dragMarks[index]) {
|
279 |
candidate[index][0] = draggingCandidate[index][0] + dragOffsetX;
|
|
|
286 |
Redraw();
|
287 |
}
|
288 |
|
289 |
+
function handleMouseUp(event) {
|
290 |
+
isDragging = false;
|
291 |
+
Redraw();
|
292 |
+
}
|
293 |
+
|
294 |
+
function ModifyDragRange(delta) { dragRange = Math.max(dragRangeDelta, Math.min(512, dragRange + delta)); }
|
295 |
+
|
296 |
+
document.addEventListener('wheel', function(event) {
|
297 |
+
const deltaY = event.deltaY;
|
298 |
+
if (deltaY < 0) {ModifyDragRange(dragRangeDelta);}
|
299 |
+
if (0 < deltaY) {ModifyDragRange(-dragRangeDelta);}
|
300 |
+
Redraw();
|
301 |
+
window.setTimeout(function() { Redraw(); }, 100);
|
302 |
+
});
|
303 |
|
304 |
document.addEventListener("keydown", (event) => {
|
305 |
+
if (event.code == "BracketLeft") { ModifyDragRange(-dragRangeDelta); }
|
306 |
+
if (event.code == "BracketRight") { ModifyDragRange(dragRangeDelta); }
|
307 |
keyDownFlags[event.code] = true;
|
308 |
Redraw();
|
309 |
});
|