vladmandic / human

Human: AI-powered 3D Face Detection & Rotation Tracking, Face Description & Recognition, Body Pose Tracking, 3D Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction, Gaze Tracking, Gesture Recognition
https://vladmandic.github.io/human/demo/index.html
MIT License
2.39k stars 327 forks source link

Some questions and Types #102

Closed Nekronik closed 3 years ago

Nekronik commented 3 years ago

After using the library I got some questions:

Q1. Is the warmup method return signature correct? I'd expect it to not contain a Result.

Q2. Is it possible to only draw the face mesh and not the box?

Q3. Is it possible to customize drawing styles? Are they global or per draw method request?

Also, since I had to write better types for the gestures and it is one of your goals, this is what I got. Maybe this can help you.

type GestureFace = GestureFaceYaw | GestureFacePitch | GestureFaceEye | GestureFaceMouth;
type GestureFaceYaw = `facing ${'left' | 'camera' | 'right'}`;
type GestureFacePitch = `head ${'up' | 'down'}`;
type GestureFaceEye = `blink ${'left' | 'right'} eye`;
type GestureFaceMouth = `mouth ${number}% open`;
type GestureIris = 'iris looking at camera';
type GestureBody = GestureBodyLean | GestureBodyHand | 'i give up';
type GestureBodyLean = `leaning ${'left' | 'right'}`;
type GestureBodyHand = `raise ${'left' | 'right'} hand`;
type GestureHand = '<finger> forward <finger> up';
type Gesture = {
  face: number;
  gesture: GestureFace;
} | {
  iris: number;
  gesture: GestureIris;
} | {
  body: number;
  gesture: GestureBody;
} | {
  hand: number;
  gesture: GestureHand;
};
export type Gestures = Array<Gesture>;

The GestureHand is not complete since I did not know all the <finger> possible values.

vladmandic commented 3 years ago

Q1. Is the warmup method return signature correct? I'd expect it to not contain a Result.

warmup returns result which i use in automated tests, otherwise warmup return values should be ignored.
Note that warmup internally is just a detect call with different preprocessing and using embedded test images.

Q2. Is it possible to only draw the face mesh and not the box?

Sure, by setting human.draw.drawOptions.drawBoxes = false

Q3. Is it possible to customize drawing styles?

Yes, you can customize it via human.draw.drawOptions object

Entire draw class is documented in https://vladmandic.github.io/human/typedoc/classes/human.html#draw

Are they global or per draw method request?

Currently they are global. But its a good idea to have a local override, I'll add that today and update here when done.

Also, since I had to write better types for the gestures and it is one of your goals, this is what I got. Maybe this can help you.

Why do you need such strong typing for gestures? I didn't create fixed typings for it because gestures are considered expandable - idea is that user can add additional gesture detections (although that code to provide user-level functions is not yet published)

Nekronik commented 3 years ago

Thanks, I was not aware of the typedoc site.

Why do you need such strong typing for gestures?

To ensure I don't misspell any of the provided gestures.

I didn't create fixed typings for it because gestures are considered expandable - idea is that user can add additional gesture detections (although that code to provide user-level functions is not yet published)

I was no aware of it. Depending on the implementation of this feature the gestures could be strongly typed for the pre-defined ones and just a matter of providing a generic with the type of the user-defined gestures.

vladmandic commented 3 years ago

how about a compromise - strongly type gesture.part, but leave gesture itself as generic.

  gesture: Array<
    { 'face': number, gesture: string } | { 'iris': number, gesture: string } | { 'body': number, gesture: string } | { 'hand': number, gesture: string }
  >,
Nekronik commented 3 years ago

This would work, up to you, you know the library roadmap better than me :) I will keep it strongly typed on my end.

But this would be an improvement anyway since right now I have to do

result.gesture as unknown as Gestures

because result.gesture has a

Result.gesture: {
    part: string;
    gesture: string;
}[]

signature, instead of

Result.gesture: {
    [part: string]: number; // <-- This part is what we are talking about
    gesture: string;
}[]
vladmandic commented 3 years ago

btw, i've just implemented global/local draw options.

human.draw.options is global (will bump version to 1.5 as this renames existing `human.draw.drawOptions) and each human.draw.* method accepts optional parameter drawOptions which is used to override global options for that draw method only.

and human.draw.options are now defined as strongly typed interface :)

new version will be published later today.

i think that was the last part of this issue, so i'll close it for now.