-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathml5-handpose.recho.js
More file actions
124 lines (115 loc) · 5.82 KB
/
ml5-handpose.recho.js
File metadata and controls
124 lines (115 loc) · 5.82 KB
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
/**
* @title ASCII Hands with Ml5.js HandPose
* @author Bairui Su
* @created 2025-09-21
* @pull_request 115
* @github pearmini
* @thumbnail_start 40
* @label ASCII Art
*/
/**
* ============================================================================
* = ASCII Hands with Ml5.js HandPose =
* ============================================================================
*
* Wave your hands to see the effect!
*
* This example shows how to use **Ml5** HandPose to detect hands and draw them
* on the screen. Also, it shows how to use **p5** to create a capture video
* element and remove it after the video is no longer needed.
*
* Note that we use ml5 **async constructor** to create the handPose object,
* which is what I worked on this summer as a ml5 researcher to support p5 2.0
* async setup. The async constructor is a new feature in ml5 1.0.0.
*
* You can check out the original pull request here:
* https://github.com/ml5js/ml5-next-gen/pull/258
*
* You can check out the original issue here:
* https://github.com/ml5js/ml5-next-gen/issues/244
*/
const width = 96;
const height = 30;
const scaleX = d3.scaleLinear([0, 640], [0, width]);
const scaleY = d3.scaleLinear([0, 480], [0, height]);
const video = await createCapture(640, 480);
const handPose = await ml5.handPose(video); // Async constructor!!!
//➜ ................................................................................................
//➜ .............@..................................................................................
//➜ ....................@...........................................................................
//➜ ....@.......@...................................................................................
//➜ ....@..............@.........@..........................@.......................................
//➜ ...........@..................................................@.................................
//➜ ....@.............@........@...................@.........@....@.................................
//➜ ........................@.............................................@.........................
//➜ ................................................@........@....@.................................
//➜ ....@....@.....@.................................@...................@..........................
//➜ ...................@................................................@...........................
//➜ ..................................@......................@......................................
//➜ .....................................................@.......@..................................
//➜ .............................@...................................@..............................
//➜ ................................................................................................
//➜ ......................@................@...@....................................................
//➜ ..............@.................................................................................
//➜ ....@............................................@..............................................
//➜ ......................................................@.........................................
//➜ .............................................................@..................................
//➜ ................................................................................................
//➜ ................................................................................................
//➜ ................................................................................................
//➜ ................................................................................................
//➜ ................................................................................................
//➜ ................................................................................................
//➜ ................................................................................................
//➜ ................................................................................................
//➜ ................................................................................................
//➜ ................................................................................................
handPose.detectStart(video, (hands) => {
const buffer = d3.range(width * height).map(() => ".");
for (let i = 0; i < hands.length; i++) {
const hand = hands[i];
for (let j = 0; j < hand.keypoints.length; j++) {
const points = hand.keypoints[j];
const x = ~~scaleX(points.x);
const y = ~~scaleY(points.y);
if (x > 0 && x < width && y > 0 && y < height) buffer[y * width + x] = "@";
}
}
let output = "";
for (let i = 0; i < height; ++i) {
for (let j = 0; j < width; ++j) output += buffer[i * width + j];
output += i === height - 1 ? "" : "\n";
}
echo.clear();
echo(output);
});
{
echo.dispose(() => removeCapture(video));
}
// Use p5 to create a capture video element.
function createCapture(width, height) {
return new Promise((resolve) => {
new p5((p) => {
p.setup = () => {
p.noCanvas();
p.noLoop();
const video = p.createCapture(p.VIDEO);
video.size(width, height);
video.hide();
resolve(video);
};
});
});
}
// Remove the capture video element.
function removeCapture(video) {
if (video) {
if (video.elt && video.elt.srcObject) {
video.elt.srcObject.getTracks().forEach((track) => track.stop());
}
video.remove();
}
}
const ml5 = await recho.require("https://unpkg.com/ml5@1/dist/ml5.js");
const p5 = await recho.require("https://unpkg.com/p5@1.2.0/lib/p5.js");
const d3 = await recho.require("d3-array", "d3-scale");