-
Notifications
You must be signed in to change notification settings - Fork 10
/
posenet.html
160 lines (151 loc) · 7.53 KB
/
posenet.html
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<html>
<head>
<title>postnet</title>
<meta charset="utf-8">
<script src="script/tfjs.1.3.1.js"></script>
<script src="script/posenet.js"></script>
</head>
<body>
<h1>姿态检测</h1>
<div id="demo" style="position: relative;min-height: 50px">
<!--视频-->
<div id="wrap" style="width:640px;height:480px;position:relative;display: none">
<video id="video" width="640" height="480" autoplay></video>
<img src="https://ossweb-img.qq.com/images/game/brand/game-logo.png" id="logo" alt="" style="display:none">
</div>
<!--图片-->
<div id="upload" style="display:none;position: absolute;z-index:99">
<input id="img_input" type="file" accept="image/*" onchange="uploadPic(event)"/>
<label for="img_input"></label>
</div>
<!--图片预览-->
<div id="preview"></div>
<!--canvas-->
<canvas id="draw" style="position: absolute;left:0;top:0;z-index:9;width:0px;height:0px;z-index:9;"></canvas>
</div>
<!--状态-->
<p id="status"></p>
<p>官方地址:<a href="https://github.com/tensorflow/tfjs-models/tree/master/posenet">https://github.com/tensorflow/tfjs-models/tree/master/posenet</a></p>
<p>前端智能DEMO合集:<a href="http://allan5.com/FE-AI/">http://allan5.com/FE-AI/</a></p>
<script>
let net = null;
let c = document.getElementById('draw');
let ctx = c.getContext('2d');
let canvasVideoSize = {'width':640,'height':480}
const status = document.getElementById('status')
let video = document.getElementById('video');
window.addEventListener("DOMContentLoaded", function() {
let video = document.getElementById('video');
let mediaConfig = {
'audio': false,
'video': {
facingMode: 'user',
width: 640,
height: 480,
}
};
//加载模型
loadModel();
if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(mediaConfig).then(function(stream) {
document.getElementById('wrap').style.display = 'block';
video.srcObject = stream;
video.play();
video.onloadeddata = function(){
//用requestAnimationFrame执行pose函数
step(video)
}
}).catch(e=>{
//不支持摄像头显示图片逻辑
document.getElementById('upload').style.display = 'block'
});
}
}, false);
//图片
function uploadPic(e){
let file = e.target.files[0];
if (!file.type.match('image.*')) return;
let reader = new FileReader();
let PREVIEW = document.getElementById('preview');
reader.readAsDataURL(file);
status.innerText = '正在预测..'
reader.onload = function(e){
PREVIEW.innerHTML = '';
PREVIEW.innerHTML = `<img id="pic" src='${e.target.result}' >`;
let image = new Image();
image.src= e.target.result;
image.onload = function () {
//在image加载后重设canvas大小对象
canvasVideoSize = {'width':image.width,'height':image.height}
//预测
pose(image)
}
}
}
//加载模型
async function loadModel(){
status.innerText = '正在加载模型...'
net = await posenet.load({
modelUrl:'model/posenet/model-stride16.json'
})
status.innerText = '模型加载完成'
}
//预测主函数
async function pose(o){
if(!net) return;
const pose = await net.estimateMultiplePoses(o, {
flipHorizontal: false
});
status.innerText = ''
console.log(pose)
//结果大于0
if(pose.length > 0){
ctx.clearRect(0,0,0,0);
//初始化canvas width height
c.width = canvasVideoSize.width;
c.height = canvasVideoSize.height;
c.style.height = canvasVideoSize.height;
c.style.width = canvasVideoSize.width;
pose.forEach(p=>{
if(p.score > 0.3){
p.keypoints.forEach(e => {
draw(e)
});
const adjacentKeyPoints = posenet.getAdjacentKeyPoints(p.keypoints, 0.3)
adjacentKeyPoints.forEach((e)=>{
drawSkeleton(e)
})
}
})
}else{
console.log('没有发现人体')
}
}
//绘制坐标点
function draw(e) {
ctx.beginPath()
//设置绘制颜色
ctx.fillStyle="aqua";
//绘制成矩形
ctx.fillRect(e.position.x-2,e.position.y-2,4,4);
//挂件
// let img = document.getElementById('logo')
// if(e.part == 'nose'){
// ctx.drawImage(img,e.position.x-img.width/2,e.position.y-img.height/2,310,80)
// }
}
//绘制骨架
function drawSkeleton(e) {
ctx.moveTo(e[0].position.x , e[0].position.y )
ctx.lineTo(e[1].position.x , e[1].position.y )
ctx.lineWidth = 2
ctx.strokeStyle = `aqua`
ctx.stroke()
}
function step() {
pose(video)
window.requestAnimationFrame(step);
}
</script>
</body>
</html>