-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
executable file
·123 lines (98 loc) · 2.89 KB
/
index.js
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
// DOM
const inner = document.getElementById("inner");
/**
* 顔のワイヤーフレームが表示されるcanvas
* @type {HTMLCanvasElement}
*/
const wireframe = document.getElementById("wireframe");
const wireframeContext = wireframe.getContext("2d");
/** @type HTMLVideoElement */
const video = document.getElementById("video");
/**
* ログ表示用
* @type {HTMLDivElement}
*/
const log = document.getElementById("log");
// Stats
const stats = new Stats();
stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
document.body.appendChild(stats.dom);
// clmtrackr
let ctrack;
// 処理開始
start();
/**
* 処理開始
*/
async function start() {
drawLog("Webカメラ読込中...");
// clmtrackrをインスタンス化
ctrack = new clm.tracker();
// MediaStream APIでWebカメラへアクセス
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
});
// videoのメタデータの取得が成功
video.addEventListener("loadedmetadata", (event) => {
// videoのサイズを取得
const videoW = video.clientWidth;
const videoH = video.clientHeight;
// windowの横幅を取得
const windowW = inner.clientWidth;
// windowの横幅と動画の横幅の比率を算出
const videoRate = windowW / videoW;
// サイズを設定
video.width = wireframe.width = windowW;
video.height = wireframe.height = videoH * videoRate;
// 繰り返し処理開始
loop();
drawLog("顔検出中...");
// 顔を検出できたときのEvent
document.addEventListener("clmtrackrConverged", clmtrackrConvergedHandler);
// 顔を検出できなかったときのEvent
document.addEventListener("clmtrackrLost", clmtrackrLostHandler);
// 顔のモデルデータを設定
ctrack.init(pModel);
// 顔の検出を開始
ctrack.start(video);
loop();
});
// videoでWebカメラの映像を表示
video.srcObject = stream;
}
/**
* 繰り返し処理
*/
function loop() {
requestAnimationFrame(loop);
// Stats計測開始
stats.begin();
// canvasの描画をクリア
wireframeContext.clearRect(0, 0, wireframe.width, wireframe.height);
// 座標が取得できたかどうか
if (ctrack.getCurrentPosition()) {
// ワイヤーフレームを描画
ctrack.draw(wireframe);
}
// Stats計測終了
stats.end();
}
/**
* 顔検出失敗
*/
function clmtrackrLostHandler() {
drawLog("顔検出失敗");
}
/**
* 顔検出成功
*/
function clmtrackrConvergedHandler() {
drawLog("顔検出成功");
}
/**
* ログを表示
* @param str {String}
*/
function drawLog(str) {
log.textContent = str;
}