mirror of https://github.com/vladmandic/human
update
parent
c4a353787a
commit
a363a08633
|
@ -9,8 +9,10 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
### **HEAD -> main** 2021/04/18 mandic00@live.com
|
### **HEAD -> main** 2021/04/19 mandic00@live.com
|
||||||
|
|
||||||
|
- added demo load image from http
|
||||||
|
- mobile demo optimization and iris gestures
|
||||||
- full test run
|
- full test run
|
||||||
- full rebuild
|
- full rebuild
|
||||||
- new look
|
- new look
|
||||||
|
|
|
@ -7,9 +7,10 @@ import Menu from './helpers/menu.js';
|
||||||
import GLBench from './helpers/gl-bench.js';
|
import GLBench from './helpers/gl-bench.js';
|
||||||
import webRTC from './helpers/webrtc.js';
|
import webRTC from './helpers/webrtc.js';
|
||||||
|
|
||||||
// const userConfig = { backend: 'webgl' }; // add any user configuration overrides
|
const userConfig = {};
|
||||||
let human;
|
let human;
|
||||||
|
|
||||||
|
/*
|
||||||
const userConfig = {
|
const userConfig = {
|
||||||
backend: 'humangl',
|
backend: 'humangl',
|
||||||
async: false,
|
async: false,
|
||||||
|
@ -18,7 +19,7 @@ const userConfig = {
|
||||||
videoOptimized: false,
|
videoOptimized: false,
|
||||||
filter: {
|
filter: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
flip: true,
|
flip: false,
|
||||||
},
|
},
|
||||||
face: { enabled: true,
|
face: { enabled: true,
|
||||||
mesh: { enabled: true },
|
mesh: { enabled: true },
|
||||||
|
@ -33,6 +34,7 @@ const userConfig = {
|
||||||
// body: { enabled: true, modelPath: 'efficientpose.json' },
|
// body: { enabled: true, modelPath: 'efficientpose.json' },
|
||||||
// object: { enabled: true },
|
// object: { enabled: true },
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
// ui options
|
// ui options
|
||||||
const ui = {
|
const ui = {
|
||||||
|
|
|
@ -94,7 +94,7 @@ async function detect(input) {
|
||||||
if (result && result.body && result.body.length > 0) {
|
if (result && result.body && result.body.length > 0) {
|
||||||
for (let i = 0; i < result.body.length; i++) {
|
for (let i = 0; i < result.body.length; i++) {
|
||||||
const body = result.body[i];
|
const body = result.body[i];
|
||||||
log.data(` Body: #${i} score:${body.score}`);
|
log.data(` Body: #${i} score:${body.score} landmarks:${body.keypoints?.length || body.landmarks?.length}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.data(' Body: N/A');
|
log.data(' Body: N/A');
|
||||||
|
|
|
@ -14,6 +14,7 @@ let fx;
|
||||||
export function process(input, config): { tensor: typeof tf.Tensor | null, canvas: OffscreenCanvas | HTMLCanvasElement } {
|
export function process(input, config): { tensor: typeof tf.Tensor | null, canvas: OffscreenCanvas | HTMLCanvasElement } {
|
||||||
let tensor;
|
let tensor;
|
||||||
if (!input) throw new Error('Human: Input is missing');
|
if (!input) throw new Error('Human: Input is missing');
|
||||||
|
// sanity checks since different browsers do not implement all dom elements
|
||||||
if (
|
if (
|
||||||
!(input instanceof tf.Tensor)
|
!(input instanceof tf.Tensor)
|
||||||
&& !(typeof Image !== 'undefined' && input instanceof Image)
|
&& !(typeof Image !== 'undefined' && input instanceof Image)
|
||||||
|
@ -28,9 +29,11 @@ export function process(input, config): { tensor: typeof tf.Tensor | null, canva
|
||||||
throw new Error('Human: Input type is not recognized');
|
throw new Error('Human: Input type is not recognized');
|
||||||
}
|
}
|
||||||
if (input instanceof tf.Tensor) {
|
if (input instanceof tf.Tensor) {
|
||||||
|
// if input is tensor, use as-is
|
||||||
if (input.shape && input.shape.length === 4 && input.shape[0] === 1 && input.shape[3] === 3) tensor = tf.clone(input);
|
if (input.shape && input.shape.length === 4 && input.shape[0] === 1 && input.shape[3] === 3) tensor = tf.clone(input);
|
||||||
else throw new Error(`Human: Input tensor shape must be [1, height, width, 3] and instead was ${input.shape}`);
|
else throw new Error(`Human: Input tensor shape must be [1, height, width, 3] and instead was ${input.shape}`);
|
||||||
} else {
|
} else {
|
||||||
|
// check if resizing will be needed
|
||||||
const originalWidth = input['naturalWidth'] || input['videoWidth'] || input['width'] || (input['shape'] && (input['shape'][1] > 0));
|
const originalWidth = input['naturalWidth'] || input['videoWidth'] || input['width'] || (input['shape'] && (input['shape'][1] > 0));
|
||||||
const originalHeight = input['naturalHeight'] || input['videoHeight'] || input['height'] || (input['shape'] && (input['shape'][2] > 0));
|
const originalHeight = input['naturalHeight'] || input['videoHeight'] || input['height'] || (input['shape'] && (input['shape'][2] > 0));
|
||||||
let targetWidth = originalWidth;
|
let targetWidth = originalWidth;
|
||||||
|
@ -43,6 +46,8 @@ export function process(input, config): { tensor: typeof tf.Tensor | null, canva
|
||||||
targetHeight = maxSize;
|
targetHeight = maxSize;
|
||||||
targetWidth = targetHeight * originalWidth / originalHeight;
|
targetWidth = targetHeight * originalWidth / originalHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create our canvas and resize it if needed
|
||||||
if (config.filter.width > 0) targetWidth = config.filter.width;
|
if (config.filter.width > 0) targetWidth = config.filter.width;
|
||||||
else if (config.filter.height > 0) targetWidth = originalWidth * (config.filter.height / originalHeight);
|
else if (config.filter.height > 0) targetWidth = originalWidth * (config.filter.height / originalHeight);
|
||||||
if (config.filter.height > 0) targetHeight = config.filter.height;
|
if (config.filter.height > 0) targetHeight = config.filter.height;
|
||||||
|
@ -54,20 +59,22 @@ export function process(input, config): { tensor: typeof tf.Tensor | null, canva
|
||||||
if (inCanvas?.height !== targetHeight) inCanvas.height = targetHeight;
|
if (inCanvas?.height !== targetHeight) inCanvas.height = targetHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw input to our canvas
|
||||||
const ctx = inCanvas.getContext('2d');
|
const ctx = inCanvas.getContext('2d');
|
||||||
if (input instanceof ImageData) {
|
if (input instanceof ImageData) {
|
||||||
ctx.putImageData(input, 0, 0);
|
ctx.putImageData(input, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
if (!config.filter.flip) {
|
if (config.filter.flip && typeof ctx.translate !== 'undefined') {
|
||||||
ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, inCanvas?.width, inCanvas?.height);
|
|
||||||
} else {
|
|
||||||
ctx.translate(originalWidth, 0);
|
ctx.translate(originalWidth, 0);
|
||||||
ctx.scale(-1, 1);
|
ctx.scale(-1, 1);
|
||||||
ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, inCanvas?.width, inCanvas?.height);
|
ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, inCanvas?.width, inCanvas?.height);
|
||||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
ctx.setTransform(1, 0, 0, 1, 0, 0); // resets transforms to defaults
|
||||||
|
} else {
|
||||||
|
ctx.drawImage(input, 0, 0, originalWidth, originalHeight, 0, 0, inCanvas?.width, inCanvas?.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// imagefx transforms using gl
|
||||||
if (config.filter.enabled) {
|
if (config.filter.enabled) {
|
||||||
if (!fx || !outCanvas || (inCanvas.width !== outCanvas.width) || (inCanvas?.height !== outCanvas?.height)) {
|
if (!fx || !outCanvas || (inCanvas.width !== outCanvas.width) || (inCanvas?.height !== outCanvas?.height)) {
|
||||||
outCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(inCanvas?.width, inCanvas?.height) : document.createElement('canvas');
|
outCanvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(inCanvas?.width, inCanvas?.height) : document.createElement('canvas');
|
||||||
|
@ -118,6 +125,8 @@ export function process(input, config): { tensor: typeof tf.Tensor | null, canva
|
||||||
outCanvas = inCanvas;
|
outCanvas = inCanvas;
|
||||||
if (fx) fx = null;
|
if (fx) fx = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create tensor from image
|
||||||
let pixels;
|
let pixels;
|
||||||
if (outCanvas.data) { // if we have data, just convert to tensor
|
if (outCanvas.data) { // if we have data, just convert to tensor
|
||||||
const shape = [outCanvas.height, outCanvas.width, 3];
|
const shape = [outCanvas.height, outCanvas.width, 3];
|
||||||
|
|
2
wiki
2
wiki
|
@ -1 +1 @@
|
||||||
Subproject commit ffe0a307e50a6f5f14f14cd01ce9e11647746ca3
|
Subproject commit 97aef7ac17b481de7768c8540a2207f61adb635b
|
Loading…
Reference in New Issue