mirror of https://github.com/vladmandic/human
fix box clamping and raw output
parent
4819930e43
commit
8523da07b5
|
@ -1,2 +1,3 @@
|
||||||
node_modules
|
node_modules
|
||||||
private
|
private
|
||||||
|
pnpm-lock.yaml
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# @vladmandic/human
|
# @vladmandic/human
|
||||||
|
|
||||||
Version: **1.1.7**
|
Version: **1.1.8**
|
||||||
Description: **Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition**
|
Description: **Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition**
|
||||||
|
|
||||||
Author: **Vladimir Mandic <mandic00@live.com>**
|
Author: **Vladimir Mandic <mandic00@live.com>**
|
||||||
|
@ -11,9 +11,12 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
|
||||||
|
|
||||||
### **HEAD -> main** 2021/03/17 mandic00@live.com
|
### **HEAD -> main** 2021/03/17 mandic00@live.com
|
||||||
|
|
||||||
|
- hierarchical readme notes
|
||||||
|
|
||||||
### **origin/main** 2021/03/17 mandic00@live.com
|
### **1.1.8** 2021/03/17 mandic00@live.com
|
||||||
|
|
||||||
|
- add experimental nanodet object detection
|
||||||
|
- full models signature
|
||||||
- cleanup
|
- cleanup
|
||||||
|
|
||||||
### **1.1.7** 2021/03/16 mandic00@live.com
|
### **1.1.7** 2021/03/16 mandic00@live.com
|
||||||
|
|
|
@ -2,3 +2,24 @@
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
Use your best judgement
|
||||||
|
If it will possibly make others uncomfortable, do not post it
|
||||||
|
|
||||||
|
- Be respectful
|
||||||
|
Disagreement is not an opportunity to attack someone else's thoughts or opinions. Although views may differ, remember to approach every situation with patience and care
|
||||||
|
- Be considerate
|
||||||
|
Think about how your contribution will affect others in the community
|
||||||
|
- Be open minded
|
||||||
|
Embrace new people and new ideas. Our community is continually evolving and we welcome positive change
|
||||||
|
|
||||||
|
Be mindful of your language
|
||||||
|
Any of the following behavior is unacceptable:
|
||||||
|
|
||||||
|
- Offensive comments of any kind
|
||||||
|
- Threats or intimidation
|
||||||
|
- Sexually explicit material
|
||||||
|
- Or any other kinds of harassment
|
||||||
|
|
||||||
|
If you believe someone is violating the code of conduct, we ask that you report it
|
||||||
|
|
||||||
|
Participants asked to stop any harassing behavior are expected to comply immediately
|
||||||
|
|
20
CONTRIBUTING
20
CONTRIBUTING
|
@ -1,3 +1,23 @@
|
||||||
# Human Library: Contributing Guidelines
|
# Human Library: Contributing Guidelines
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
Pull requests from everyone are welcome
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Procedure for contributing:
|
||||||
|
- Create a fork of the repository on github
|
||||||
|
In a top right corner of a GitHub, select "Fork"
|
||||||
|
- Clone your forked repository to your local system
|
||||||
|
`git clone https://github.com/<your-username>/<your-fork>
|
||||||
|
- Make your changes
|
||||||
|
- Test your changes against code guidelines
|
||||||
|
`npm run lint`
|
||||||
|
- Push changes to your fork
|
||||||
|
- Submit a PR (pull request) to `Human`
|
||||||
|
<https://github.com/vladmandic/human/pulls>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Your pull request will be reviewed and pending review results, merged into main branch
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
# Human Library: Security Policy
|
# Human Library: Security Policy
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
All issues are tracked publicly on GitHub
|
||||||
|
|
||||||
|
Entire code base and indluded dependencies is automatically scanned against known security vulnerabilities
|
||||||
|
|
|
@ -5,8 +5,8 @@ After=network.target network-online.target
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
Environment="NODE_ENV=production"
|
Environment="NODE_ENV=production"
|
||||||
ExecStart=/home/vlado/.nvm/versions/node/v15.7.0/bin/node server/serve.js
|
ExecStart=<path-to-node> server/serve.js
|
||||||
WorkingDirectory=/home/vlado/dev/human
|
WorkingDirectory=<your-project-folder>
|
||||||
StandardOutput=inherit
|
StandardOutput=inherit
|
||||||
StandardError=inherit
|
StandardError=inherit
|
||||||
Restart=always
|
Restart=always
|
||||||
|
|
11
src/draw.ts
11
src/draw.ts
|
@ -18,6 +18,7 @@ export const drawOptions = {
|
||||||
useDepth: <Boolean>true,
|
useDepth: <Boolean>true,
|
||||||
useCurves: <Boolean>false,
|
useCurves: <Boolean>false,
|
||||||
bufferedOutput: <Boolean>false,
|
bufferedOutput: <Boolean>false,
|
||||||
|
useRawBoxes: <Boolean>false,
|
||||||
};
|
};
|
||||||
|
|
||||||
function point(ctx, x, y, z = null) {
|
function point(ctx, x, y, z = null) {
|
||||||
|
@ -121,8 +122,8 @@ export async function face(inCanvas, result) {
|
||||||
ctx.strokeStyle = drawOptions.color;
|
ctx.strokeStyle = drawOptions.color;
|
||||||
ctx.fillStyle = drawOptions.color;
|
ctx.fillStyle = drawOptions.color;
|
||||||
if (drawOptions.drawBoxes) {
|
if (drawOptions.drawBoxes) {
|
||||||
rect(ctx, f.box[0], f.box[1], f.box[2], f.box[3]);
|
if (drawOptions.useRawBoxes) rect(ctx, inCanvas.width * f.boxRaw[0], inCanvas.height * f.boxRaw[1], inCanvas.width * f.boxRaw[2], inCanvas.height * f.boxRaw[3]);
|
||||||
// rect(ctx, inCanvas.width * f.boxRaw[0], inCanvas.height * f.boxRaw[1], inCanvas.width * f.boxRaw[2], inCanvas.height * f.boxRaw[3]);
|
else rect(ctx, f.box[0], f.box[1], f.box[2], f.box[3]);
|
||||||
}
|
}
|
||||||
// silly hack since fillText does not suport new line
|
// silly hack since fillText does not suport new line
|
||||||
const labels:string[] = [];
|
const labels:string[] = [];
|
||||||
|
@ -305,7 +306,8 @@ export async function hand(inCanvas, result) {
|
||||||
if (drawOptions.drawBoxes) {
|
if (drawOptions.drawBoxes) {
|
||||||
ctx.strokeStyle = drawOptions.color;
|
ctx.strokeStyle = drawOptions.color;
|
||||||
ctx.fillStyle = drawOptions.color;
|
ctx.fillStyle = drawOptions.color;
|
||||||
rect(ctx, h.box[0], h.box[1], h.box[2], h.box[3]);
|
if (drawOptions.useRawBoxes) rect(ctx, inCanvas.width * h.boxRaw[0], inCanvas.height * h.boxRaw[1], inCanvas.width * h.boxRaw[2], inCanvas.height * h.boxRaw[3]);
|
||||||
|
else rect(ctx, h.box[0], h.box[1], h.box[2], h.box[3]);
|
||||||
if (drawOptions.drawLabels) {
|
if (drawOptions.drawLabels) {
|
||||||
if (drawOptions.shadowColor && drawOptions.shadowColor !== '') {
|
if (drawOptions.shadowColor && drawOptions.shadowColor !== '') {
|
||||||
ctx.fillStyle = drawOptions.shadowColor;
|
ctx.fillStyle = drawOptions.shadowColor;
|
||||||
|
@ -357,7 +359,8 @@ export async function object(inCanvas, result) {
|
||||||
if (drawOptions.drawBoxes) {
|
if (drawOptions.drawBoxes) {
|
||||||
ctx.strokeStyle = drawOptions.color;
|
ctx.strokeStyle = drawOptions.color;
|
||||||
ctx.fillStyle = drawOptions.color;
|
ctx.fillStyle = drawOptions.color;
|
||||||
rect(ctx, h.box[0], h.box[1], h.box[2] - h.box[0], h.box[3] - h.box[1]);
|
if (drawOptions.useRawBoxes) rect(ctx, inCanvas.width * h.boxRaw[0], inCanvas.height * h.boxRaw[1], inCanvas.width * h.boxRaw[2], inCanvas.height * h.boxRaw[3]);
|
||||||
|
else rect(ctx, h.box[0], h.box[1], h.box[2], h.box[3]);
|
||||||
if (drawOptions.drawLabels) {
|
if (drawOptions.drawLabels) {
|
||||||
const label = `${Math.round(100 * h.score)}% ${h.label}`;
|
const label = `${Math.round(100 * h.score)}% ${h.label}`;
|
||||||
if (drawOptions.shadowColor && drawOptions.shadowColor !== '') {
|
if (drawOptions.shadowColor && drawOptions.shadowColor !== '') {
|
||||||
|
|
|
@ -29,7 +29,7 @@ export class HandPose {
|
||||||
async estimateHands(input, config) {
|
async estimateHands(input, config) {
|
||||||
const predictions = await this.handPipeline.estimateHands(input, config);
|
const predictions = await this.handPipeline.estimateHands(input, config);
|
||||||
if (!predictions) return [];
|
if (!predictions) return [];
|
||||||
const hands: Array<{ confidence: number, box: any, landmarks: any, annotations: any }> = [];
|
const hands: Array<{ confidence: number, box: any, boxRaw: any, landmarks: any, annotations: any }> = [];
|
||||||
for (const prediction of predictions) {
|
for (const prediction of predictions) {
|
||||||
const annotations = {};
|
const annotations = {};
|
||||||
if (prediction.landmarks) {
|
if (prediction.landmarks) {
|
||||||
|
@ -40,10 +40,16 @@ export class HandPose {
|
||||||
const box = prediction.box ? [
|
const box = prediction.box ? [
|
||||||
Math.max(0, prediction.box.topLeft[0]),
|
Math.max(0, prediction.box.topLeft[0]),
|
||||||
Math.max(0, prediction.box.topLeft[1]),
|
Math.max(0, prediction.box.topLeft[1]),
|
||||||
Math.min(input.shape[2], prediction.box.bottomRight[0]) - prediction.box.topLeft[0],
|
Math.min(input.shape[2], prediction.box.bottomRight[0]) - Math.max(0, prediction.box.topLeft[0]),
|
||||||
Math.min(input.shape[1], prediction.box.bottomRight[1]) - prediction.box.topLeft[1],
|
Math.min(input.shape[1], prediction.box.bottomRight[1]) - Math.max(0, prediction.box.topLeft[1]),
|
||||||
] : 0;
|
] : [];
|
||||||
hands.push({ confidence: prediction.confidence, box, landmarks: prediction.landmarks, annotations });
|
const boxRaw = [
|
||||||
|
(prediction.box.topLeft[0]) / input.shape[2],
|
||||||
|
(prediction.box.topLeft[1]) / input.shape[1],
|
||||||
|
(prediction.box.bottomRight[0] - prediction.box.topLeft[0]) / input.shape[2],
|
||||||
|
(prediction.box.bottomRight[1] - prediction.box.topLeft[1]) / input.shape[1],
|
||||||
|
];
|
||||||
|
hands.push({ confidence: prediction.confidence, box, boxRaw, landmarks: prediction.landmarks, annotations });
|
||||||
}
|
}
|
||||||
return hands;
|
return hands;
|
||||||
}
|
}
|
||||||
|
|
13
src/human.ts
13
src/human.ts
|
@ -54,6 +54,7 @@ export type Result = {
|
||||||
hand: Array<{
|
hand: Array<{
|
||||||
confidence: Number,
|
confidence: Number,
|
||||||
box: [Number, Number, Number, Number],
|
box: [Number, Number, Number, Number],
|
||||||
|
boxRaw: [Number, Number, Number, Number],
|
||||||
landmarks: Array<[Number, Number, Number]>,
|
landmarks: Array<[Number, Number, Number]>,
|
||||||
annotations: Array<{ part: String, points: Array<[Number, Number, Number]>[] }>,
|
annotations: Array<{ part: String, points: Array<[Number, Number, Number]>[] }>,
|
||||||
}>,
|
}>,
|
||||||
|
@ -595,7 +596,17 @@ export class Human {
|
||||||
|
|
||||||
this.#perf.total = Math.trunc(now() - timeStart);
|
this.#perf.total = Math.trunc(now() - timeStart);
|
||||||
this.state = 'idle';
|
this.state = 'idle';
|
||||||
resolve({ face: faceRes, body: bodyRes, hand: handRes, gesture: gestureRes, object: objectRes, performance: this.#perf, canvas: process.canvas });
|
const result = {
|
||||||
|
face: faceRes,
|
||||||
|
body: bodyRes,
|
||||||
|
hand: handRes,
|
||||||
|
gesture: gestureRes,
|
||||||
|
object: objectRes,
|
||||||
|
performance: this.#perf,
|
||||||
|
canvas: process.canvas,
|
||||||
|
};
|
||||||
|
// log('Result:', result);
|
||||||
|
resolve(result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,10 +49,10 @@ async function process(res, inputSize, outputShape, config) {
|
||||||
];
|
];
|
||||||
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1))); // fix out-of-bounds coords
|
boxRaw = boxRaw.map((a) => Math.max(0, Math.min(a, 1))); // fix out-of-bounds coords
|
||||||
const box = [ // results normalized to input image pixels
|
const box = [ // results normalized to input image pixels
|
||||||
boxRaw[0] * outputShape[0],
|
Math.max(0, (boxRaw[0] * outputShape[0])),
|
||||||
boxRaw[1] * outputShape[1],
|
Math.max(0, (boxRaw[1] * outputShape[1])),
|
||||||
boxRaw[2] * outputShape[0],
|
Math.min(1, (boxRaw[2] * outputShape[0]) - (boxRaw[0] * outputShape[0])),
|
||||||
boxRaw[3] * outputShape[1],
|
Math.min(1, (boxRaw[3] * outputShape[1]) - (boxRaw[1] * outputShape[1])),
|
||||||
];
|
];
|
||||||
const result = {
|
const result = {
|
||||||
score: scoresMax[i],
|
score: scoresMax[i],
|
||||||
|
|
2
wiki
2
wiki
|
@ -1 +1 @@
|
||||||
Subproject commit 99c3d70ec78fbbe0d12528c1d4b18ba1d27fef0d
|
Subproject commit 91af84e9543762c4f31be41dda15fb2a5549d8a6
|
Loading…
Reference in New Issue