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 |
});
|