Piarasingh85 commited on
Commit
815a443
·
verified ·
1 Parent(s): 849e4a9

Create app.js

Browse files
Files changed (1) hide show
  1. app.js +193 -0
app.js ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2023 The MediaPipe Authors.
2
+
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import {
16
+ PoseLandmarker,
17
+ FilesetResolver,
18
+ DrawingUtils
19
+ } from "https://cdn.skypack.dev/@mediapipe/tasks-vision@0.10.0";
20
+
21
+ const demosSection = document.getElementById("demos");
22
+
23
+ let poseLandmarker: PoseLandmarker = undefined;
24
+ let runningMode = "IMAGE";
25
+ let enableWebcamButton: HTMLButtonElement;
26
+ let webcamRunning: Boolean = false;
27
+ const videoHeight = "360px";
28
+ const videoWidth = "480px";
29
+
30
+ // Before we can use PoseLandmarker class we must wait for it to finish
31
+ // loading. Machine Learning models can be large and take a moment to
32
+ // get everything needed to run.
33
+ const createPoseLandmarker = async () => {
34
+ const vision = await FilesetResolver.forVisionTasks(
35
+ "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/wasm"
36
+ );
37
+ poseLandmarker = await PoseLandmarker.createFromOptions(vision, {
38
+ baseOptions: {
39
+ modelAssetPath: `https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task`,
40
+ delegate: "GPU"
41
+ },
42
+ runningMode: runningMode,
43
+ numPoses: 2
44
+ });
45
+ demosSection.classList.remove("invisible");
46
+ };
47
+ createPoseLandmarker();
48
+
49
+ /********************************************************************
50
+ // Demo 1: Grab a bunch of images from the page and detection them
51
+ // upon click.
52
+ ********************************************************************/
53
+
54
+ // In this demo, we have put all our clickable images in divs with the
55
+ // CSS class 'detectionOnClick'. Lets get all the elements that have
56
+ // this class.
57
+ const imageContainers = document.getElementsByClassName("detectOnClick");
58
+
59
+ // Now let's go through all of these and add a click event listener.
60
+ for (let i = 0; i < imageContainers.length; i++) {
61
+ // Add event listener to the child element whichis the img element.
62
+ imageContainers[i].children[0].addEventListener("click", handleClick);
63
+ }
64
+
65
+ // When an image is clicked, let's detect it and display results!
66
+ async function handleClick(event) {
67
+ if (!poseLandmarker) {
68
+ console.log("Wait for poseLandmarker to load before clicking!");
69
+ return;
70
+ }
71
+
72
+ if (runningMode === "VIDEO") {
73
+ runningMode = "IMAGE";
74
+ await poseLandmarker.setOptions({ runningMode: "IMAGE" });
75
+ }
76
+ // Remove all landmarks drawed before
77
+ const allCanvas = event.target.parentNode.getElementsByClassName("canvas");
78
+ for (var i = allCanvas.length - 1; i >= 0; i--) {
79
+ const n = allCanvas[i];
80
+ n.parentNode.removeChild(n);
81
+ }
82
+
83
+ // We can call poseLandmarker.detect as many times as we like with
84
+ // different image data each time. The result is returned in a callback.
85
+ poseLandmarker.detect(event.target, (result) => {
86
+ const canvas = document.createElement("canvas");
87
+ canvas.setAttribute("class", "canvas");
88
+ canvas.setAttribute("width", event.target.naturalWidth + "px");
89
+ canvas.setAttribute("height", event.target.naturalHeight + "px");
90
+ canvas.style =
91
+ "left: 0px;" +
92
+ "top: 0px;" +
93
+ "width: " +
94
+ event.target.width +
95
+ "px;" +
96
+ "height: " +
97
+ event.target.height +
98
+ "px;";
99
+
100
+ event.target.parentNode.appendChild(canvas);
101
+ const canvasCtx = canvas.getContext("2d");
102
+ const drawingUtils = new DrawingUtils(canvasCtx);
103
+ for (const landmark of result.landmarks) {
104
+ drawingUtils.drawLandmarks(landmark, {
105
+ radius: (data) => DrawingUtils.lerp(data.from!.z, -0.15, 0.1, 5, 1)
106
+ });
107
+ drawingUtils.drawConnectors(landmark, PoseLandmarker.POSE_CONNECTIONS);
108
+ }
109
+ });
110
+ }
111
+
112
+ /********************************************************************
113
+ // Demo 2: Continuously grab image from webcam stream and detect it.
114
+ ********************************************************************/
115
+
116
+ const video = document.getElementById("webcam") as HTMLVideoElement;
117
+ const canvasElement = document.getElementById(
118
+ "output_canvas"
119
+ ) as HTMLCanvasElement;
120
+ const canvasCtx = canvasElement.getContext("2d");
121
+ const drawingUtils = new DrawingUtils(canvasCtx);
122
+
123
+ // Check if webcam access is supported.
124
+ const hasGetUserMedia = () => !!navigator.mediaDevices?.getUserMedia;
125
+
126
+ // If webcam supported, add event listener to button for when user
127
+ // wants to activate it.
128
+ if (hasGetUserMedia()) {
129
+ enableWebcamButton = document.getElementById("webcamButton");
130
+ enableWebcamButton.addEventListener("click", enableCam);
131
+ } else {
132
+ console.warn("getUserMedia() is not supported by your browser");
133
+ }
134
+
135
+ // Enable the live webcam view and start detection.
136
+ function enableCam(event) {
137
+ if (!poseLandmarker) {
138
+ console.log("Wait! poseLandmaker not loaded yet.");
139
+ return;
140
+ }
141
+
142
+ if (webcamRunning === true) {
143
+ webcamRunning = false;
144
+ enableWebcamButton.innerText = "ENABLE PREDICTIONS";
145
+ } else {
146
+ webcamRunning = true;
147
+ enableWebcamButton.innerText = "DISABLE PREDICTIONS";
148
+ }
149
+
150
+ // getUsermedia parameters.
151
+ const constraints = {
152
+ video: true
153
+ };
154
+
155
+ // Activate the webcam stream.
156
+ navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
157
+ video.srcObject = stream;
158
+ video.addEventListener("loadeddata", predictWebcam);
159
+ });
160
+ }
161
+
162
+ let lastVideoTime = -1;
163
+ async function predictWebcam() {
164
+ canvasElement.style.height = videoHeight;
165
+ video.style.height = videoHeight;
166
+ canvasElement.style.width = videoWidth;
167
+ video.style.width = videoWidth;
168
+ // Now let's start detecting the stream.
169
+ if (runningMode === "IMAGE") {
170
+ runningMode = "VIDEO";
171
+ await poseLandmarker.setOptions({ runningMode: "VIDEO" });
172
+ }
173
+ let startTimeMs = performance.now();
174
+ if (lastVideoTime !== video.currentTime) {
175
+ lastVideoTime = video.currentTime;
176
+ poseLandmarker.detectForVideo(video, startTimeMs, (result) => {
177
+ canvasCtx.save();
178
+ canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);
179
+ for (const landmark of result.landmarks) {
180
+ drawingUtils.drawLandmarks(landmark, {
181
+ radius: (data) => DrawingUtils.lerp(data.from!.z, -0.15, 0.1, 5, 1)
182
+ });
183
+ drawingUtils.drawConnectors(landmark, PoseLandmarker.POSE_CONNECTIONS);
184
+ }
185
+ canvasCtx.restore();
186
+ });
187
+ }
188
+
189
+ // Call this function again to keep predicting when the browser is ready.
190
+ if (webcamRunning === true) {
191
+ window.requestAnimationFrame(predictWebcam);
192
+ }
193
+ }