Spaces:
Running
Running
File size: 4,009 Bytes
987f315 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
class Posenet2Scratch {
constructor(runtime) {
this.runtime = runtime;
this.poses = [];
this.keypoints = [];
this._locale = this.setLocale();
const video = document.createElement("video");
video.width = 480;
video.height = 360;
video.autoplay = true;
video.style.display = "none";
navigator.mediaDevices
.getUserMedia({ video: true, audio: false })
.then((stream) => {
video.srcObject = stream;
});
video.addEventListener("loadeddata", () => {
// Load posenet model and process poses
posenet.load().then((net) => {
const detectPose = () => {
net.estimateMultiplePoses(video, {
flipHorizontal: false,
}).then((poses) => {
this.poses = poses;
this.keypoints = poses[0]?.keypoints || [];
requestAnimationFrame(detectPose);
});
};
detectPose();
});
});
this.runtime.ioDevices.video.enableVideo();
}
setLocale() {
const supportedLocales = ["en", "ja", "ja-Hira"];
const locale = navigator.language || "en";
return supportedLocales.includes(locale) ? locale : "en";
}
getX(args) {
const personIndex = parseInt(args.PERSON_NUMBER, 10) - 1;
const partIndex = parseInt(args.PART, 10);
const pose = this.poses[personIndex];
if (pose && pose.pose.keypoints[partIndex]) {
const x = pose.pose.keypoints[partIndex].position.x;
return this.runtime.ioDevices.video.mirror ? 240 - x : x - 240;
}
return "";
}
getY(args) {
const personIndex = parseInt(args.PERSON_NUMBER, 10) - 1;
const partIndex = parseInt(args.PART, 10);
const pose = this.poses[personIndex];
if (pose && pose.pose.keypoints[partIndex]) {
const y = pose.pose.keypoints[partIndex].position.y;
return 180 - y;
}
return "";
}
getPeopleCount() {
return this.poses.length;
}
getInfo() {
return {
id: "posenet2scratch",
name: "Posenet2Scratch",
blocks: [
{
opcode: "getX",
blockType: "reporter",
text: "[PART] x of person no. [PERSON_NUMBER]",
arguments: {
PERSON_NUMBER: { type: "string", menu: "personNumbers", defaultValue: "1" },
PART: { type: "string", menu: "parts", defaultValue: "0" },
},
},
{
opcode: "getY",
blockType: "reporter",
text: "[PART] y of person no. [PERSON_NUMBER]",
arguments: {
PERSON_NUMBER: { type: "string", menu: "personNumbers", defaultValue: "1" },
PART: { type: "string", menu: "parts", defaultValue: "0" },
},
},
{
opcode: "getPeopleCount",
blockType: "reporter",
text: "people count",
},
],
menus: {
personNumbers: {
acceptReporters: true,
items: Array.from({ length: 10 }, (_, i) => ({ text: `${i + 1}`, value: `${i + 1}` })),
},
parts: {
acceptReporters: true,
items: [
{ text: "nose", value: "0" },
{ text: "left eye", value: "1" },
{ text: "right eye", value: "2" },
{ text: "left ear", value: "3" },
{ text: "right ear", value: "4" },
{ text: "left shoulder", value: "5" },
{ text: "right shoulder", value: "6" },
{ text: "left elbow", value: "7" },
{ text: "right elbow", value: "8" },
{ text: "left wrist", value: "9" },
{ text: "right wrist", value: "10" },
{ text: "left hip", value: "11" },
{ text: "right hip", value: "12" },
{ text: "left knee", value: "13" },
{ text: "right knee", value: "14" },
{ text: "left ankle", value: "15" },
{ text: "right ankle", value: "16" },
],
},
},
};
}
}
Scratch.extensions.register(new Posenet2Scratch());
|