Code Monkey home page Code Monkey logo

handtrack.js's Introduction

Handtrack.js

npm version npm

View a live demo in your browser here.

Note: Version 0.0.13 is the old version of handtrack.js which tracks only hands and was trained on the egohands dataset. It is slightly more stable than the recent version v 0.1.x which is trained on a new dataset (still in active development) and supports more classes (open, closed, pinch, point, zoom etc.). You might see some issues with the new version (feel free to downgrade to 0.0.13 as needed) and also report the issues you see.

Handtrack.js is a library for prototyping realtime hand detection (bounding box), directly in the browser. It frames handtracking as an object detection problem, and uses a trained convolutional neural network to predict bounding boxes for the location of hands in an image.

Whats New? v0.1.x

Handtrack.js is currently being updated (mostly around optimizations for speed/accuracy and functionality). Here is a list of recent changes:

  • New dataset curation: A new dataset (~2000 images, 6000 labels) has been curated to cover new hand poses (discussed below) and focuses on the viewpoint of a user facing a webcam. Note that the dataset is not released (mostly because it contains personal information on the participants and effort is still underway to extract a subset that is free of PII). In the meantime, the project can still be reproduced using the egohands dataset which is public.

  • New Classes: Following a review of the use cases that developers have created so far with handtrack.js (e.g. game controls, detect face touching to minimize covid spread, air guitar etc), a new set of hand pose labels have been curated:

    • Open: All fingers are extended in an open palm position. This represents an open hand which can be the drop mode of a drag and drop operation.
    • Closed: All fingers are contracted in a ball in a closed fist position. The closed hand is similar to the drag mode for a drag and drop operation.
    • Pinch: The thumb and index finger are are together in an picking gesture. This can also double as a grab or drag mode in a drag and drop operation.
    • Point: Index finger is extended in a pointing gesture.
    • Face: To help disambiguate between the face and hands (a failure point for the previous version of handtrack.js), and to also enable face tracking applications in the same library, a face label has been added.
  • Reduced Model size: Handtrack.js now supports multiple models (e.g. ssd320fpnlite, ssd640fpnlite) with multiple sizes (large, medium and small). The large size is the default fp32 version of the each model while medium and small are fp16 and Int8 quantized versions respectively. In my experiments, the small version yields comparable accuracy but with a much smaller model weight size. For example, ssd320fpnlite sizes (large -> 12MB, medium -> 6MB, small -> 3MB!)

Note that smaller models don't translate to faster inference speed - all three sizes yield about the same FPS.

  • Model Accuracy: Early testing shows the new model to be more accurate for the front facing web cam viewpoint detection. The inclusion of face labels also reduces the earlier face misclassifications
  • Javascript Library: The handtrack.js library has been updated to fix issues with correct input image resolutions, upgrade the underlying tensorflowjs models, provide more customization options (e.g. use of small medium or large base models etc)

The underlying models are trained using the tensorflow object detection api (see here).

FPS Image Size Device Browser Comments
26 450 * 380 Macbook Pro (i7, 2.2GHz, 2018) Chrome Version 72.0.3626 --
14 450 * 380 Macbook Pro (i7, 2.2GHz, mid 2014) Chrome Version 72.0.3626 --

Note: Handtrack.js has not been extensively tested on mobile browsers. There have been some known inconsistencies still being investigated.

Documentation

Handtrack.js is provided as a useful wrapper to allow you prototype hand/gesture based interactions in your web applications. without the need to understand machine learning. It takes in a html image element (img, video, canvas elements, for example) and returns an array of bounding boxes, class names and confidence scores.

Import the Handtrack.js Library

Note that the current version of the handtrack.js library is designed to work in the browser (frontend Javascript) and not Node.js.

Handtrack.js can be imported into your application either via a script tag or via npm. Once imported, handtrack.js provides an asynchronous load() method which returns a promise for a object detection model object.

Import via Script Tag

<!-- Load the handtrackjs model. -->
<script src="https://cdn.jsdelivr.net/npm/handtrackjs@latest/dist/handtrack.min.js"> </script>

<!-- Replace this with your image. Make sure CORS settings allow reading the image! -->
<img id="img" src="hand.jpg"/>  

<!-- Place your code in the script tag below. You can also use an external .js file -->
<script>
  const img = document.getElementById('img'); 
  const model =  await handTrack.load();
  const predictions = await model.detect(img); 
</script>

via NPM

npm install --save handtrackjs
import * as handTrack from 'handtrackjs';

const img = document.getElementById('img'); 
const model =  await handTrack.load();
const predictions = await model.detect(img); 

Handtrack.js also proivdes a set of library helper methods (e.g. to start and stop video playback on a video element) and some model methods (e.g. detect, getFPS etc). Please see the project documentation page for more details on the API and examples.

How does Handtrack.js Work?

  • Trained using a dataset of annotated hand poses (open, closed, pointing, pinch ..) mostly captured from a user webcam viewpoint. This is also augmented with samples from other viewpoints (round table discussion participants, egocentric viewpoints) and varied lighting conditions. An earlier version of handtrack.js was trained with the egohands dataset.
  • Trained model is converted to the Tensorflowjs webmodel format
  • Model is wrapped into an npm package, and can be accessed using jsdelivr, a free open source cdn that lets you include any npm package in your web application. You may notice the model is loaded slowly the first time the page is opened but gets faster on subsequent loads (caching).

When Should I Use Handtrack.js

If you are interested in prototyping gesture based (body as input) interactive experiences, Handtrack.js can be useful. The user does not need to attach any additional sensors or hardware but can immediately take advantage of engagement benefits that result from gesture based and body-as-input interactions.

Some (not all) relevant scenarios are listed below:ย 

  • When mouse motion can be mapped to hand motion for control purposes.
  • When an overlap of hand and other objects can represent meaningful interaction signals (e.g a touch or selection event for an object).
  • Scenarios where the human hand motion can be a proxy for activity recognition (e.g. automatically tracking movement activity from a video or images of individuals playing chess). Or simply counting how many humans are present in an image or video frame.
  • You want an accessible demonstration that anyone can easily run or tryout with minimal setup.
  • You are interested in usecases that have offline, realtime, privacy requirements.

Limitations

The main limitation currently is that handtrack.js is still a fairly heavy model and there have been some inconsistent results when run on mobile.

Run Demo

Commands below runs the demo example in the demo folder.

npm install
npm run start

The start script launches a simple python3 webserver from the demo folder using http.server. You should be able to view it in your browser at http://localhost:3005/. You can also view the pong game control demo on same link http://localhost:3005/pong.html

Citing this Work (see abstract)

Paper abstract of the paper is here. (a full paper will be added when complete).

If you use this code in your project/paper/research and would like to cite this work, use the below.

Victor Dibia, HandTrack: A Library For Prototyping Real-time Hand TrackingInterfaces using Convolutional Neural Networks, https://github.com/victordibia/handtracking

@article{Dibia2017,
  author = {Victor, Dibia},
  title = {HandTrack: A Library For Prototyping Real-time Hand TrackingInterfaces using Convolutional Neural Networks},
  year = {2017},
  publisher = {GitHub},
  journal = {GitHub repository},
  url = {https://github.com/victordibia/handtracking/tree/master/docs/handtrack.pdf}, 
}

TODO (ideas welcome)

  • Optimization: This thing is still compute heavy (your fans may spin after while). This is mainly because of the neural net operations needed to predict bounding boxes. I am currently exploring CenterNets (an anchor free object detection model) as one way to minimize compute requirements.

  • Tracking id's across frames. Perhaps some nifty methods that assigns ids to each had as they enter a frame and tracks them (e.g based on naive euclidean distance).

  • Add some discrete poses (e.g. instead of just hand, detect open hand, closed, ).

handtrack.js's People

Contributors

dependabot[bot] avatar victordibia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

handtrack.js's Issues

Tracking hand rotation?

Hi! This is such an awesome project! ๐Ÿ™‡

I was wondering how hard would it be to add hand rotation tracking?
My use case is turning virtual knobs in the air for live music/video applications.

Thanks!

Cannot detect for live camera?

Hi author,
I'm trying to detect hand of two cameras in my conference like below image. But the result always return null. Could you help me? Thanks
Here is my code:
const largeVideo = ((document.getElementById('largeVideo'): any): HTMLVideoElement);
const localVideo = ((document.getElementById('localVideo_container'): any): HTMLVideoElement);
// Load the model.
const defaultParams = {
flipHorizontal: false,
modelType: "ssd640fpnlite",
modelSize: "medium",
};
handTrack.load(defaultParams).then(model => {
console.log("model loaded");
setTimeout(() => { clearInterval(checkHighFive); }, 6000);
checkHighFive = setInterval(()=>{
let localHand = false;
model.detect(localVideo).then(predictions => {
console.log('Predictions localVideo: ', predictions);
if(predictions.lenght > 0 && predictions[0].label == "open"){
localHand = true;
}
});
model.detect(remoteVideo).then(predictions => {
console.log('Predictions remoteVideo: ', predictions);
if(predictions.lenght > 0 && predictions[0].label == "open" && localHand){
this.props.dispatch(highFive(true));
setTimeout(() => { this.props.dispatch(highFive(false)); }, 4000);
this.props.conference.sendCommandOnce('HIGH_FIVE', { value:_participant.id });
clearInterval(checkHighFive);
}
});
}, 500);
})
image

Error during npm start

$ npm start

[email protected] start /private/tmp/handtrack.js
cross-env NODE_ENV=development parcel demo/index.html --open

events.js:167
throw er; // Unhandled 'error' event
^

Error: spawn parcel ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:232:19)
at onErrorNT (internal/child_process.js:407:16)
at process._tickCallback (internal/process/next_tick.js:63:19)
at Function.Module.runMain (internal/modules/cjs/loader.js:744:11)
at startup (internal/bootstrap/node.js:285:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:739:3)
Emitted 'error' event at:
at Process.ChildProcess._handle.onexit (internal/child_process.js:238:12)
at onErrorNT (internal/child_process.js:407:16)
[... lines matching original stack trace ...]
at bootstrapNodeJSCore (internal/bootstrap/node.js:739:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: cross-env NODE_ENV=development parcel demo/index.html --open
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! /Users/abib/.npm/_logs/2019-03-13T10_17_17_633Z-debug.log

Webcam faces wrong direction

When I tried to use this demo on my Microsoft Surface computer, the webcam detection was working with the front-facing webcam instead of the rear-facing webcam, so it was facing away from my keyboard. Could this demo be modified to allow switching webcams, so that it will work correctly on computers with more than one webcam?

model question: relationship to main repo, input sizes, unknown kernel ops

i just stumbled on your model and so far i really like it

i do have few questions:

what is the relationship of two different models?

notes state that tfjs graph model is just converted from tf model, but model signatures,
internal operations and sizes (when manually converted and equally quantized) do not match?

what is the correct model input size?

model input size is marked as dynamic shape: [1, -1, -1, 3],
but models model names indicate 320 for ssd320fpnlite and 640 for ssd640fpnlite ?
and notes further confuse the issue since they state that both models are trained on inputs 450 * 380 ???

tfjs graph model has unknown operations

tensorlistreserve, enter, tensorlistfromtensor, merge, loopcond, switch,
exit, tensorliststack, nextiteration, tensorlistsetitem, tensorlistgetitem,
reciprocal, shape, split, where

those ops are not supported by tfjs, but it seems it doesn't impact model execution at all
(defined but unused?)

and one request for enhancement - predict hand rotation

my use case is so the hand detection model can be comined with other models
(e.g. detailed finger tracking, gesture analysis, sign language recognition, etc.)

the thing is, all those models are trained on vertially oriented hand
if hand detection model returned approximate rotation angle, then image could be
rotated and cropped before being used for further analysis

Using my own model

I tried to train a smaller size ssdmobilenetv1 model and convert it into tfjs_graph_model format๏ผŒbut how can I use it in the project? Is it necessary to modify the handtrack.min.js code because I found basepath and defaultParams variables in it . Any help would be greatly appreciated!!

How to track hand for up and down

whenever I move the hand up or down I want to press up key using hand tracking method.
Can you please provide sample code to achieve that.

Thanks

Main: dist/handtrack.min.js

Hi,

Could you please change the main property in the package.json to be the file in the distdirectory rather than the src so that this project compiles properly when used from npm?

Thanks

Cannot load model

Dear author,
I have face with this problem when try to do example
const video = document.getElementById('largeVideo');
// const canvas = document.getElementById("canvas");
// const context = canvas.getContext("2d");

    // Load the model.
    handTrack.load().then(model => {
        // detect objects in the image.
        console.log("model loaded")
        model.detect(video).then(predictions => {
            console.log('Predictions: ', predictions);
            // model.renderPredictions(predictions, canvas, context, video);
            // requestAnimationFrame(runDetection);
        });
    });

-->
"UnhandledError: Request to https://cdn.jsdelivr.net/npm/handtrackjs@latest/models/webmodel/centernet512fpn/base/model.json failed with status code 404. Please verify this URL points to the model JSON of the model to load"
Could you help me. Thanks

How to set the aspect ratio of a video stream?

Im having some issues to properly set the dimensions of the video stream for a live detection.
I can correctly set the width & height of the video element. Tough its aspect ratio always stays at 3:4.

I saw that there is a commit for this to support the safari browser, but Im not using safari and would actually prefer a 16:9 resolution. Is that an expected behaviour, or do I miss something?

Handtrack.js using for AR HELP!

Hi I want to make an AR demo for myself with using hand tracking. The project in my mind is like the Iron Man Hand cannon as 3D object on my hand and tracking it. How can I do that ? someone can explain or help me with it ? ty.

Cannot read property 'node' of undefined

I have 2 different Vue projects wich both use handtrackjs. The components which use handtrackjs are identical. In the newer project i get the following error:

Uncaught (in promise) TypeError: Cannot read property 'node' of undefined
at e.evaluateFeature (webpack-internal:///./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js:250)
at e.get (webpack-internal:///./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js:250)
at e.register (webpack-internal:///./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js:250)
at e.registerTensor (webpack-internal:///./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js:250)
at new e (webpack-internal:///./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js:250)
at Function.e.make (webpack-internal:///./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js:250)
at tensor (webpack-internal:///./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js:250)
at Module.tensor2d (webpack-internal:///./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js:250)
at eval (webpack-internal:///./node_modules/handtrackjs/src/index.js:131)
at eval (webpack-internal:///./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js:250)

Whereas in the old project everything works as expected. Both projects use the same handtrackjs version + same Vue version. Is there any hint what might cause this behaviour?

Cannot read property 'getUserMedia' of undefined

Chrome Version 81.0.4044.138 (Official Build) (64-bit)
OSX Catalina 10.15.2 (19C57)

pong.js:112 766 1440
planck-with-testbed.js:13564 On load.
planck-with-testbed.js:13193 Starting...
planck-with-testbed.js:13205 Loading apps...
planck-with-testbed.js:13156 Creating app...
planck-with-testbed.js:13592 Creating Canvas...
planck-with-testbed.js:13617 Creating stage...
planck-with-testbed.js:13159 Initing app...
planck-with-testbed.js:13165 Starting app...
planck-with-testbed.js:13662 Resize: 2880 x 1532 / 2
pong.js:205 ready!
5handtrack.min.js:25 Uncaught (in promise) TypeError: Cannot read property 'getUserMedia' of undefined
at handtrack.min.js:25
at new Promise ()
at Object.startVideo (handtrack.min.js:25)
at startVideo (pong.js:30)
at toggleVideo (pong.js:45)
at HTMLButtonElement. (pong.js:57)
planck-with-testbed.js:13662 Resize: 1362 x 1532 / 2
DevTools failed to load SourceMap: Could not load content for chrome-extension://hdokiejnpimakedhajhdlcegeplioahd/sourcemaps/onloadwff.js.map: HTTP error: status code 404, net::ERR_UNKNOWN_URL_SCHEME

WebGL warning : Browser freeze when using Handtrack.js

Hi!

I am using Handtrack.js which works well, however after a few minutes of use my browser freezes. I can't do anything with my computer, except hardly turning it off with the start button.

In my browser I have the following warning: WebGL warning: getBufferSubData: Reading from a buffer with usage other than *_READ causes pipeline stalls. Copy through a STREAM_READ buffer. refering to the file handtrack.min.js which I think is the origin of my problem.

Do you know if there's a solution for the multiple freezes ? I saw there's already a fixed issue in the Tensorflow.js project. Does Handtrack.js have a recent version of Tensorflow.js ?

I'm blocked in my work.. Thank :)

Camera freezing on iOS Safari

When trying to use the basic example on iOS Safari (iPhone 11 Pro), and toggling video, it either shows all black or just what shows on the camera for the first frame - then freezes.

I've stopped runDetection(); running within the startVideo() function when camera is enabled to rule this out, and the same behaviour occurred then.

Ignoring Faces?

Hello everyone,
we are creating a simple gesture app that will understand when hands move from left to right and viceverse.
The problem that we are finding is that if the user has it camera point to the face, the default config always detect faces and the hand over the face is never recognized.
Is there any way to configure handtrackjs to ignore faces vs hands ?

Regards

import statement error in node.js

Hello. Whenever I install the handtrackjs package in Node.js, and run my project, I get the following error:

(node:2780) ExperimentalWarning: The ESM module loader is experimental.
/Users/me/Documents/Projects/MCH/node_modules/handtrackjs/src/index.js:11
import * as tf from '@tensorflow/tfjs';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:1053:16)
    at Module._compile (internal/modules/cjs/loader.js:1101:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
    at Module.load (internal/modules/cjs/loader.js:985:32)
    at Function.Module._load (internal/modules/cjs/loader.js:878:14)
    at ModuleWrap.<anonymous> (internal/modules/esm/translators.js:155:15)
    at ModuleJob.run (internal/modules/esm/module_job.js:139:37)
    at async Loader.import (internal/modules/esm/loader.js:179:24)

I think the package could use a transition to CommonJS (or maybe it's something on my end)

Getting class value of 0

In the prediction, I got:

{bbox: Array(4), class: 0, score: 0.985114336013794}

Per documentation, I would expect "hand", correct?

Thanks for your time.

in How to remove the post processing part of the object detection model graph during conversion

Hey. I am facing the following issue during conversion of fozengraph model to .js format.

In your (awesome) blog you mentioned that

I followed the suggestion by authors of the Tensorflow coco-ssd example [2] in removing the post-processing part of the object detection model graph during conversion.

So I went to that link and executed the command in the readme file :

tensorflowjs_converter --input_format=tf_frozen_model \
                       --output_format=tfjs_graph_model \
                       --output_node_names='Postprocessor/ExpandDims_1,Postprocessor/Slice' \
                       ./frozen_inference_graph.pb \
                       ./web_model

But with my frcnn - inception v2 model I am getting this error:

KeyError: "The name 'Postprocessor/Slice' refers to an Operation not in the graph."

And when I am trying to convert SSD_MobileNet_V2, I am getting this error:

ValueError: Unsupported Ops in the model before optimization
NonMaxSuppressionV5

tensorflowjs version 1.3.2
tensorflow version 1.15.0

Any help would be much, much appreciated.
Thank you.

Need Help in Integrating with A-Frame webgl context

I am trying to integrate A-Frame with handtracking.js but not successfull.
Here's the code: https://woolen-windy-legal.glitch.me

When I see Console ,I get error:

Uncaught (in promise) TypeError: Cannot read property height of null
at getInputTensorDimensions (handtrack.min.js:25)
at ObjectDetection.detect (handtrack.min.js:42)
at runDetection (aframe.html:49)
at aframe.html:60

Please help me fix this !!!

Using api in Python

How can I use the API in the web based python application. Do I include the js source code in html code of the app and then directly import with load() in the python code or what?

Demo breaking with the JSDelivr load

I tried cloning the repo just to check out the demo - both index and pong break with seemingly the same issue:

Uncaught ReferenceError: require is not defined                                                                      handtrack.min.js:2464:294
    <anonymous> https://cdn.jsdelivr.net/npm/handtrackjs@latest/dist/handtrack.min.js:2464
    <anonymous> https://cdn.jsdelivr.net/npm/handtrackjs@latest/dist/handtrack.min.js:1
    <anonymous> https://cdn.jsdelivr.net/npm/handtrackjs@latest/dist/handtrack.min.js:1

and

Uncaught TypeError: handTrack.load is not a function
    <anonymous> http://localhost:3005/js/index.js:86

If I switch to loading from <script src="lib/handtrack.js"> </script> instead of JSDelivr everything runs fine. But loading from <script src="handtrack.min.js"> </script> produces the same error. (seems like the libs folder still has the older version from 2018).

The same thing happens when trying to run this example https://github.com/victordibia/handtrack.js#import-via-script-tag :

Uncaught ReferenceError: require is not defined                                                                        handtrack.min.js:2464:294
    <anonymous> https://cdn.jsdelivr.net/npm/handtrackjs@latest/dist/handtrack.min.js:2464
    <anonymous> https://cdn.jsdelivr.net/npm/handtrackjs@latest/dist/handtrack.min.js:1
    <anonymous> https://cdn.jsdelivr.net/npm/handtrackjs@latest/dist/handtrack.min.js:1

and
Uncaught SyntaxError: await is only valid in async functions and async generators index.html:21:22

Line 22 in index.html is const predictions = await model.detect(img); from the example

code error, realtime handtrack is not working

Hi

https://victordibia.github.io/handtrack.js/#/doodle on chrome, i've got the js error below when clicking on Start Video doodle

react-dom.production.min.js:232 Uncaught TypeError: Cannot read property 'then' of undefined
    at t.value (Doodle.jsx:164)
    at Object.<anonymous> (react-dom.production.min.js:49)
    at p (react-dom.production.min.js:69)
    at react-dom.production.min.js:73
    at S (react-dom.production.min.js:140)
    at T (react-dom.production.min.js:169)
    at N (react-dom.production.min.js:158)
    at D (react-dom.production.min.js:232)
    at En (react-dom.production.min.js:1718)
    at Is (react-dom.production.min.js:5990)

Same thing for https://victordibia.github.io/handtrack.js/#/ when clicking on button Start Video

post-processing optimization suggestion (with code)

currently handdetector.js module downloads all results and processes per-class scores in js before going back to tfjs
which causes large dataset transfers from tfjs backend
(either gpu (when used with webgl tfjs backend) or from within webassembly context (when used with wasm tfjs backend))
and then recreate required tensor and upload it back to tfjs backend

that is a double unnecessary round-trip for data plus cpu intensive processing loop in js

a much more efficient approach is to handle as much processing as possible using tfjs and only download final results
(not to mention much shorter code)

async function detectHands(input: Tensor, outputSize = [1, 1]) {
  const hands = tf.tidy(() => {
    const [rawScores, rawBoxes] = await models.executeAsync(tensor, modelOutputNodes);
    const boxes = tf.squeeze(rawBoxes, [0, 2]); // remove zero-dims 
    const scores = tf.squeeze(rawScores, [0]); // remove zero-dims 
    const classScores = tf.unstack(scores, 1); // split all-scores into individual per-class scores
    const hands = [];
    // now lets process data once per each class
    // could also be used to process only some classes, e.g. skip face if desired
    for (let i = 0; i < classScores.length; i++) {
      // get best results for each class
      nmsT = await tf.image.nonMaxSuppressionAsync(boxes, classScores[i], maxDetected, iouThreshold, minConfidence);
      const nms = await nmsT.data();
      for (const res of nms) { // now process only those best results
        const boxSlice = tf.slice(t.boxes, res, 1); // download just the box we need
        const yxBox = await boxSlice.data();
        // convert [y1,x1,y1,x2] to [x,y,width,height]
        const boxRaw = [yxBox[1], yxBox[0], yxBox[3] - yxBox[1], yxBox[2] - yxBox[0]];
        // scale back to original resolution
        const box = [Math.trunc(boxRaw[0] * outputSize[0]), Math.trunc(boxRaw[1] * outputSize[1]), Math.trunc(boxRaw[2] * outputSize[0]), Math.trunc(boxRaw[3] * outputSize[1])];
        const scoreSlice = tf.slice(classScores[i], res, 1); // download just the score we need
        const score = await scoreSlice.data();
        const hand = { score: score[0], box, boxRaw, class: classes[i] };
        hands.push(hand);
      }
    }
    return hands; 
  })
}

i'd post this as PR, but it's total change of the library, so posting here instead...

.hth.

Mobile version?

Hello, I wasn't able to get this to run in my phone's browser. Do you have a version of this code that can?
Thank you.

Memory leaking?

Actually, I am facing this problem when I tried to write some code using OpenCV.js, so I want to find out how others solve this problem, but your demo seems have same problem, the usage of memory of the browser is keep increasing. The JavaScript didn't recycle the memory correctly. I am not sure am I right or wrong, because i am new to AI and web.

handTrack.load is not a function

It seems like I can't use it with import * as handTrack from

I am getting this error: handTrack.load is not a function

When I use the traditional script loading ti works but as soon I load via <script type="module"> I get the above error.

J

what is maxNumBoxes mean?

First, thank you for creating this library. ๐Ÿ™

I was wondering while reading the Reade.me file.
For maxNumBoxes,
Does this parameter mean load count for one time?
or
the maximum value I can load?(If I put 20 in maxNumBoxes, will modal be delete after load 20 boxes?)

thank you ๐Ÿ˜„

Add issue templates or forms

Context

Adding issue templates or forms for bug reports, features, documentation updates, etc. can help to ensure that all the necessary information is collected from contributors and--in some cases--can lead to answers and closed issues.

Resources

This guide explains how to do it, and if you're interested in seeing forms in action, you can check out our issue forms.

How do I build this (using e.g. `npm run build`)?

I tried installing a fresh node environment:

twn$ nodeenv --prebuilt nodeenv
 * Install node (15.5.1)... done.
twn$ source nodeenv/bin/activate
(nodeenv)twn$ npm install

added 380 packages, and audited 381 packages in 4s

4 vulnerabilities (3 low, 1 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.
(nodeenv)twn$ npm install --global

added 1 package, and audited 3 packages in 472ms

found 0 vulnerabilities

Then I tried to run build:

(nodeenv)twn$ npm run build

> [email protected] build
> rollup -c

sh: 1: rollup: not found
npm ERR! code 127
npm ERR! path /home/twn/repos/github.com/victordibia/handtrack.js
npm ERR! command failed
npm ERR! command sh -c rollup -c

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/twn/.npm/_logs/2021-01-07T20_53_32_648Z-debug.log

Okay so I tried installing rollup:

(nodeenv)twn$ npm install rollup
npm WARN deprecated [email protected]: "Please update to latest v2.3 or v2.2"

added 2 packages, and audited 383 packages in 1s

4 vulnerabilities (3 low, 1 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.
(nodeenv)twn$ npm install --global rollup
npm WARN deprecated [email protected]: "Please update to latest v2.3 or v2.2"

added 2 packages, and audited 3 packages in 509ms

found 0 vulnerabilities

Then I tried running build again:

(nodeenv)twn$ npm run build

> [email protected] build
> rollup -c


src/index.js โ†’ dist/handtrack.min.js, demo/handtrack.min.js...
(!) Use of eval is strongly discouraged
https://rollupjs.org/guide/en/#avoiding-eval
node_modules/@tensorflow/tfjs-converter/dist/tf-converter.esm.js
15:  * =============================================================================

    [ ... removed ... ]

18: //# sourceMappingURL=tf-converter.esm.js.map
[!] (plugin babel-minify) TypeError: Banner must be a valid comment.
TypeError: Banner must be a valid comment.
    at PluginPass.Program (/home/twn/repos/github.com/victordibia/handtrack.js/node_modules/@comandeer/babel-plugin-banner/dist/babel-plugin-banner.js:2:476)
    at newFn (/home/twn/repos/github.com/victordibia/handtrack.js/node_modules/@babel/traverse/lib/visitors.js:193:21)
    at NodePath._call (/home/twn/repos/github.com/victordibia/handtrack.js/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (/home/twn/repos/github.com/victordibia/handtrack.js/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (/home/twn/repos/github.com/victordibia/handtrack.js/node_modules/@babel/traverse/lib/path/context.js:88:12)
    at TraversalContext.visitQueue (/home/twn/repos/github.com/victordibia/handtrack.js/node_modules/@babel/traverse/lib/context.js:118:16)
    at TraversalContext.visitSingle (/home/twn/repos/github.com/victordibia/handtrack.js/node_modules/@babel/traverse/lib/context.js:90:19)
    at TraversalContext.visit (/home/twn/repos/github.com/victordibia/handtrack.js/node_modules/@babel/traverse/lib/context.js:146:19)
    at Function.traverse.node (/home/twn/repos/github.com/victordibia/handtrack.js/node_modules/@babel/traverse/lib/index.js:94:17)
    at traverse (/home/twn/repos/github.com/victordibia/handtrack.js/node_modules/@babel/traverse/lib/index.js:76:12)

npm ERR! code 1
npm ERR! path /home/twn/repos/github.com/victordibia/handtrack.js
npm ERR! command failed
npm ERR! command sh -c rollup -c

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/twn/.npm/_logs/2021-01-07T20_53_59_766Z-debug.log

What am I missing here? I'm sure this is something basic and obvious for those a bit more experienced with node, but I'm a little lost. By the way, I'm running

  • Debian 10
  • node version 15.5.1 (as seen above)
  • npm version 7.3.0

Thanks for any help! And thanks for the super interesting project!

frozen model to tfjs conversion

Hi, I was trying to convert your frozen model(ssd handtracking) to json format.

I'm using tensorflowjs_converter tool, I tried converting and I got output files as model.json and group1_shard files. But In handtracking.js you have generated tensorflow_model.pb, weights_mainfest.json and shard files.

Can you guide me on what you have done while conversion?

Many false detections while running on mobile device

The library runs fine on my laptop. However, when I run the online demo (even on provided images) on my mobile device (Samsung Galaxy S10e) I get a lot of false positives which confidences are 0.999.

Do you know what is happening ?

TypeError: navigator.mediaDevices is undefined

I get the error:

Uncaught (in promise) TypeError: navigator.mediaDevices is undefined
    startVideo https://cdn.jsdelivr.net/npm/handtrackjs/dist/handtrack.min.js:25
    startVideo https://cdn.jsdelivr.net/npm/handtrackjs/dist/handtrack.min.js:25

Using the following code:

    <div id="main">

        <div class="knob selected">0</div>
    </div>

    <video class="" autoplay="autoplay" id="video_tag" style="width: 300px; height: 300px; background-color: rgb(155,255,122);"></video>

    <script src="https://cdn.jsdelivr.net/npm/handtrackjs/dist/handtrack.min.js"> </script>
    
    <script>
        let tracking_webcam = false;
        const video_tag = document.getElementById('video_tag')

        const run_detection = (model, video) => {
            model.detect(video).then(predictions => {
                console.log('Predictions: ', predictions); 
            });
        }

        const track_webcam = (model, video) => {
            handTrack.startVideo(video).then(status => {
                console.log('status trying to start video: ', status)
                if (status) {
                    tracking_webcam = true;
                    run_detection(model, video)
                }
            })
        }
        // Load the model.
        console.log('Loading handtrack model')
        handTrack.load().then(model => {
            console.log('Handtrack model')
            track_webcam(model, video_tag)
        });
    </script>

The error is thrown at the following line:

handTrack.startVideo(video).then(statu...

I'm unsure what I'm doing wrong here.

the predictions are an empty array even if my hand is visible in the camera

this is my code:
`
Navigator.getUserMedia =
Navigator.getUserMedia ||
Navigator.webkitUserMedia ||
Navigator.mozUserMedia ||
Navigator.msUserMedia;
const modelParams = {
flipHorizontal: true, // flip e.g for video
imageScaleFactor: 0.7, // reduce input image size for gains in speed.
maxNumBoxes: 20, // maximum number of boxes to detect
iouThreshold: 0.5, // ioU threshold for non-max suppression
scoreThreshold: 0.79, // confidence threshold for predictions.
};

const video = document.querySelector("#video");
const audio = document.querySelector("#audio");
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
let model;
handTrack.startVidseo(video)
.then((status) => {
if (status) {
navigator.getUserMedia(
{ video: {} },
(stream) => {
video.srcObject = stream;
setInterval(doTheDetection, 1000);
},
(err) => console.log(err)
);
}
});
function doTheDetection() {

model.detect(video)
.then(pred => {
    console.log(pred);
});

}
handTrack.load(modelParams).then((lmodel) => {
model = lmodel;
`});````

this is the result:

handtrackbug

AR Hand Gesture based using THREE.js

Hello,
I want to create a hand gesture based texture changing WebAR part using THREE.js
I used the handtrack.js but in that when wrote the code of detection the phone camera is stucking. May be the phone is not responding or the code is not getting the perfect output.

Would be glad to have a response on it if anyone had worked on.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.