原文链接: tfjs posenet
上一篇: requestAnimationFrame 摄像头数据绘制到canvas
下一篇: tf hub mobile_net 使用
tfjs-model
https://github.com/tensorflow/tfjs-models/tree/master/posenet
react
https://github.com/jscriptcoder/tfjs-posenet
util
- import * as posenet from '@tensorflow-models/posenet';
-
- function isAndroid() {
- return /Android/i.test(navigator.userAgent);
- }
-
- function isiOS() {
- return /iPhone|iPad|iPod/i.test(navigator.userAgent);
- }
-
- export function isMobile() {
- return isAndroid() || isiOS();
- }
-
-
- function toTuple({y, x}) {
- return [y, x]
- }
- export function drawBoundingBox(keypoints, ctx,boundingBoxColor='blue') {
- const boundingBox = posenet.getBoundingBox(keypoints);
-
- ctx.rect(
- boundingBox.minX, boundingBox.minY, boundingBox.maxX - boundingBox.minX,
- boundingBox.maxY - boundingBox.minY);
-
- ctx.strokeStyle = boundingBoxColor;
- ctx.stroke();
- }
-
- export function drawSegment([ay, ax], [by, bx], color, scale, ctx, lineWidth = 2) {
- ctx.beginPath();
- ctx.moveTo(ax * scale, ay * scale);
- ctx.lineTo(bx * scale, by * scale);
- ctx.lineWidth = lineWidth;
- ctx.strokeStyle = color;
- ctx.stroke();
- }
-
- /**
- * Draws a pose skeleton by looking up all adjacent keypoints/joints
- */
- export function drawSkeleton(keypoints, minConfidence, ctx, scale = 1, color = 'red') {
- const adjacentKeyPoints =
- posenet.getAdjacentKeyPoints(keypoints, minConfidence);
-
- adjacentKeyPoints.forEach((keypoints) => {
- drawSegment(
- toTuple(keypoints[0].position), toTuple(keypoints[1].position), color,
- scale, ctx);
- });
- }
-
- export function drawPoint(ctx, y, x, r, color) {
- ctx.beginPath();
- ctx.arc(x, y, r, 0, 2 * Math.PI);
- ctx.fillStyle = color;
- ctx.fill();
- }
-
- export function drawKeypoints(keypoints, minConfidence, ctx, scale = 1, color = 'red') {
- for (let i = 0; i < keypoints.length; i++) {
- const keypoint = keypoints[i];
-
- if (keypoint.score < minConfidence) {
- continue;
- }
- const {y, x} = keypoint.position;
- console.log(x, y)
- drawPoint(ctx, y * scale, x * scale, 3, color);
- }
- }
vue
- <template>
- <div>
- <video id="video" class="video"></video>
- <canvas id="pose" class="pose"></canvas>
- </div>
- </template>
-
- <script>
- import * as posenet from '@tensorflow-models/posenet';
- import {isMobile, drawKeypoints, drawSkeleton, drawBoundingBox} from './utils'
-
- let VConsole = require('vconsole/dist/vconsole.min.js');
- let vConsole = new VConsole();
-
- const imageScaleFactor = 1;
- const outputStride = 16;
- const flipHorizontal = false;
- const videoWidth = 500
- const videoHeight = 500
-
-
- async function setupCamera() {
- if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
- throw new Error(
- 'Browser API navigator.mediaDevices.getUserMedia not available');
- }
-
- const video = document.getElementById('video');
- video.width = videoWidth;
- video.height = videoHeight;
-
- const mobile = isMobile();
- const stream = await navigator.mediaDevices.getUserMedia({
- 'audio': false,
- 'video': {
- facingMode: 'user',
- width: videoWidth,
- height: videoHeight,
- },
- });
- video.srcObject = stream;
- console.log(video)
- return new Promise((resolve) => {
- video.onloadedmetadata = () => {
- resolve(video);
- };
- });
- }
-
- async function loadVideo() {
- const video = await setupCamera();
- console.log(video)
- video.play();
-
- return video;
- }
-
- const minPoseConfidence = 0.1
- const minPartConfidence = 0.5
- let video = undefined
- let net = undefined
- let ctx = undefined
- let cvs = undefined
-
- async function draw_frame() {
- if (!video || !net || !ctx || !cvs)
- return
- const pose = await net.estimateSinglePose(video, imageScaleFactor, flipHorizontal, outputStride);
- let {score, keypoints} = pose
- requestAnimationFrame(draw_frame)
- ctx.drawImage(video, 0, 0, cvs.width, cvs.height)
- if (score >= minPoseConfidence) {
- drawKeypoints(keypoints, minPartConfidence, ctx);
- drawSkeleton(keypoints, minPartConfidence, ctx);
- drawBoundingBox(keypoints, ctx)
- }
- }
-
- export default {
- async mounted() {
- video = await loadVideo();
- net = await posenet.load();
- cvs = document.getElementById('pose')
- ctx = cvs.getContext('2d')
- cvs.height = 500
- cvs.width = 500
- draw_frame()
- }
- }
- </script>
-
- <style scoped>
- .video {
- max-width: 500px;
- max-height: 500px;
- border: 1px solid black;
- }
-
- .pose {
- width: 500px;
- height: 500px;
- border: 1px solid black;
- }
-
- </style>
注意版本目前2019年3月10日并不能再1.0下运行
- "@tensorflow-models/posenet": "^0.1.1",
- "@tensorflow/tfjs": "^0.11.4",