Skip to content

Commit

Permalink
feat: ia flow dev
Browse files Browse the repository at this point in the history
  • Loading branch information
ccamensuli committed Sep 27, 2023
1 parent 787d99f commit 0cf61b0
Show file tree
Hide file tree
Showing 10 changed files with 801 additions and 18 deletions.
14 changes: 7 additions & 7 deletions src/bundles/ia-bundle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
},
"dependencies": {
"@mdi/font": "7.2.96",
"@mediapipe/pose": "0.5.1675469404",
"@tensorflow-models/coco-ssd": "2.2.3",
"@tensorflow-models/mobilenet": "^2.1.0",
"@tensorflow-models/speech-commands": "^0.5.4",
"@tensorflow-models/pose-detection": "2.1.3",
"@tensorflow-models/speech-commands": "0.5.4",
"@tensorflow/tfjs": "4.11.0",
"@tensorflow/tfjs-backend-webgpu": "4.11.0",
"@tensorflow/tfjs-node": "4.11.0",
"@tensorflow/tfjs-node-gpu": "4.11.0",
"@tensorflow/tfjs-vis": "^1.5.1",
Expand All @@ -26,13 +29,13 @@
"leaflet": "^1.9.2",
"ml5": "0.12.2",
"p5": "^1.5.0",
"sass": "1.67.0",
"sass": "1.68.0",
"sass-loader": "13.3.2",
"scikitjs": "1.24.0",
"vue": "^3.2.45",
"vue-i18n": "9.4.1",
"vue-router": "^4.1.6",
"vuetify": "3.3.16",
"vue-router": "4.2.5",
"vuetify": "3.3.19",
"vuex": "^4.1.0"
},
"devDependencies": {
Expand All @@ -44,9 +47,6 @@
"@vue/cli-plugin-vuex": "5.0.8",
"@vue/cli-service": "5.0.8",
"@vue/compiler-sfc": "^3.2.45",
"babel-eslint": "^10.1.0",
"eslint": "^8.27.0",
"eslint-plugin-vue": "^9.7.0",
"expose-loader": "4.1.0",
"node-gyp": "^9.3.0",
"vue-cli-plugin-i18n": "^2.3.1",
Expand Down
8 changes: 5 additions & 3 deletions src/bundles/ia-bundle/src/compositions/coco-ssd.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import {
defineEmits
} from "vue"

import * as tfjs from '@tensorflow/tfjs';

import * as cocoSsd from '@tensorflow-models/coco-ssd'
import * as tfjs from '@tensorflow/tfjs';
import * as tf from '@tensorflow/tfjs-core';

const Cocossd = () => {

Expand All @@ -21,8 +23,8 @@ const Cocossd = () => {

})

onMounted(() => {

onMounted(async () => {
await tf.ready();
})

const getUserMediaSupported = () => {
Expand Down
231 changes: 231 additions & 0 deletions src/bundles/ia-bundle/src/compositions/motions/RendererCanvas2d.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
/**
* @license
* Copyright 2023 Google LLC.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
import * as posedetection from '@tensorflow-models/pose-detection';
import * as scatter from 'scatter-gl';

import * as params from './params';

// These anchor points allow the pose pointcloud to resize according to its
// position in the input.
const ANCHOR_POINTS = [[0, 0, 0], [0, 1, 0], [-1, 0, 0], [-1, -1, 0]];

// #ffffff - White
// #800000 - Maroon
// #469990 - Malachite
// #e6194b - Crimson
// #42d4f4 - Picton Blue
// #fabed4 - Cupid
// #aaffc3 - Mint Green
// #9a6324 - Kumera
// #000075 - Navy Blue
// #f58231 - Jaffa
// #4363d8 - Royal Blue
// #ffd8b1 - Caramel
// #dcbeff - Mauve
// #808000 - Olive
// #ffe119 - Candlelight
// #911eb4 - Seance
// #bfef45 - Inchworm
// #f032e6 - Razzle Dazzle Rose
// #3cb44b - Chateau Green
// #a9a9a9 - Silver Chalice
const COLOR_PALETTE = [
'#ffffff', '#800000', '#469990', '#e6194b', '#42d4f4', '#fabed4', '#aaffc3',
'#9a6324', '#000075', '#f58231', '#4363d8', '#ffd8b1', '#dcbeff', '#808000',
'#ffe119', '#911eb4', '#bfef45', '#f032e6', '#3cb44b', '#a9a9a9'
];
export class RendererCanvas2d {
constructor(canvas) {
this.ctx = canvas.getContext('2d');
/*this.scatterGLEl = document.querySelector('#scatter-gl-container');
this.scatterGL = new scatter.ScatterGL(this.scatterGLEl, {
'rotateOnStart': true,
'selectEnabled': false,
'styles': {polyline: {defaultOpacity: 1, deselectedOpacity: 1}}
});
this.scatterGLHasInitialized = false;*/
this.videoWidth = canvas.width;
this.videoHeight = canvas.height;
this.flip(this.videoWidth, this.videoHeight);
}

flip(videoWidth, videoHeight) {
// Because the image from camera is mirrored, need to flip horizontally.
this.ctx.translate(videoWidth, 0);
this.ctx.scale(-1, 1);

/*this.scatterGLEl.style =
`width: ${videoWidth}px; height: ${videoHeight}px;`;
this.scatterGL.resize();
this.scatterGLEl.style.display =
params.STATE.modelConfig.render3D ? 'inline-block' : 'none';*/
}

draw(rendererParams) {
const [video, poses, isModelChanged] = rendererParams;
this.drawCtx(video);

// The null check makes sure the UI is not in the middle of changing to a
// different model. If during model change, the result is from an old model,
// which shouldn't be rendered.
if (poses && poses.length > 0 && !isModelChanged) {
this.drawResults(poses);
}
}

drawCtx(video) {
this.ctx.drawImage(video, 0, 0, this.videoWidth, this.videoHeight);
}

clearCtx() {
this.ctx.clearRect(0, 0, this.videoWidth, this.videoHeight);
}

/**
* Draw the keypoints and skeleton on the video.
* @param poses A list of poses to render.
*/
drawResults(poses) {
for (const pose of poses) {
this.drawResult(pose);
}
}

/**
* Draw the keypoints and skeleton on the video.
* @param pose A pose with keypoints to render.
*/
drawResult(pose) {
if (pose.keypoints != null) {
this.drawKeypoints(pose.keypoints);
this.drawSkeleton(pose.keypoints, pose.id);
}
if (pose.keypoints3D != null && params.STATE.modelConfig.render3D) {
this.drawKeypoints3D(pose.keypoints3D);
}
}

/**
* Draw the keypoints on the video.
* @param keypoints A list of keypoints.
*/
drawKeypoints(keypoints) {
const keypointInd =
posedetection.util.getKeypointIndexBySide(params.STATE.model);
this.ctx.fillStyle = 'Red';
this.ctx.strokeStyle = 'White';
this.ctx.lineWidth = params.DEFAULT_LINE_WIDTH;

for (const i of keypointInd.middle) {
this.drawKeypoint(keypoints[i]);
}

this.ctx.fillStyle = 'Green';
for (const i of keypointInd.left) {
this.drawKeypoint(keypoints[i]);
}

this.ctx.fillStyle = 'Orange';
for (const i of keypointInd.right) {
this.drawKeypoint(keypoints[i]);
}
}

drawKeypoint(keypoint) {
// If score is null, just show the keypoint.
const score = keypoint.score != null ? keypoint.score : 1;
const scoreThreshold = params.STATE.modelConfig.scoreThreshold || 0;

if (score >= scoreThreshold) {
const circle = new Path2D();
circle.arc(keypoint.x, keypoint.y, params.DEFAULT_RADIUS, 0, 2 * Math.PI);
this.ctx.fill(circle);
this.ctx.stroke(circle);
}
}

/**
* Draw the skeleton of a body on the video.
* @param keypoints A list of keypoints.
*/
drawSkeleton(keypoints, poseId) {
// Each poseId is mapped to a color in the color palette.
const color = params.STATE.modelConfig.enableTracking && poseId != null ?
COLOR_PALETTE[poseId % 20] :
'White';
this.ctx.fillStyle = color;
this.ctx.strokeStyle = color;
this.ctx.lineWidth = params.DEFAULT_LINE_WIDTH;

posedetection.util.getAdjacentPairs(params.STATE.model).forEach(([
i, j
]) => {
const kp1 = keypoints[i];
const kp2 = keypoints[j];

// If score is null, just show the keypoint.
const score1 = kp1.score != null ? kp1.score : 1;
const score2 = kp2.score != null ? kp2.score : 1;
const scoreThreshold = params.STATE.modelConfig.scoreThreshold || 0;

if (score1 >= scoreThreshold && score2 >= scoreThreshold) {
this.ctx.beginPath();
this.ctx.moveTo(kp1.x, kp1.y);
this.ctx.lineTo(kp2.x, kp2.y);
this.ctx.stroke();
}
});
}

drawKeypoints3D(keypoints) {
const scoreThreshold = params.STATE.modelConfig.scoreThreshold || 0;
const pointsData =
keypoints.map(keypoint => ([-keypoint.x, -keypoint.y, -keypoint.z]));

const dataset =
new scatter.ScatterGL.Dataset([...pointsData, ...ANCHOR_POINTS]);

const keypointInd =
posedetection.util.getKeypointIndexBySide(params.STATE.model);
this.scatterGL.setPointColorer((i) => {
if (keypoints[i] == null || keypoints[i].score < scoreThreshold) {
// hide anchor points and low-confident points.
return '#ffffff';
}
if (i === 0) {
return '#ff0000' /* Red */;
}
if (keypointInd.left.indexOf(i) > -1) {
return '#00ff00' /* Green */;
}
if (keypointInd.right.indexOf(i) > -1) {
return '#ffa500' /* Orange */;
}
});

if (!this.scatterGLHasInitialized) {
this.scatterGL.render(dataset);
} else {
this.scatterGL.updateDataset(dataset);
}
const connections = posedetection.util.getAdjacentPairs(params.STATE.model);
const sequences = connections.map(pair => ({indices: pair}));
this.scatterGL.setSequences(sequences);
this.scatterGLHasInitialized = true;
}
}

0 comments on commit 0cf61b0

Please sign in to comment.