Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup 🧹 image argument checking #1322

Merged
merged 6 commits into from
May 12, 2022

Conversation

lindapaiste
Copy link
Contributor

Related issue #1189

handleArguments

  • Helper function handleArguments constructs and returns an instance of new ArgHelper class.
  • Reads in an array of unknown arguments and sets each argument to a named property based on its type.
  • Properties can be destructured as const { video, callback } = args or accessed as args.video.
  • Returned object has a .require method as a wrapper around error throwing, which is called as args.require('image', 'message when missing').

Utilities

  • Define boolean type guard functions for various input types (isCanvas, isVideo, etc.).
  • Define helper function getImageElement to access the underlying DOM element from p5 objects.
  • Extract common logic from utils flipImage and imgToPixelArray into function drawToCanvas.
  • Add JSDoc types to some imageUtilities functions.

Models

  • Use handleArguments to delete large chunks of repeated code from models.
  • Define JSDoc for option types and result types on BodyPix and CartoonGAN. (the types are still not 100% as VSCode doesn't auto-import @typedef from other files and WebStorm doesn't handle spread types or type guards correctly)

}
// All other objects are assumed to be options.
else {
this.options = arg;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question:

  • If multiple objects are passed, should we spread all those obj properties into this options object? 😬

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an interesting idea! I wouldn't want to encourage a situation where the user is providing multiple options objects. But it does open up some interesting possibilities for internal use:

  • We can pass the DEFAULT_OPTIONS as the first argument when parsing the arguments for constructing a model. The ArgHelper would handle merging the provided arguments with the defaults and we could take that logic out of a bunch of constructors.
  • We can merge this.options with additional options that are provided to a specific method. (For models like BodyPix where we are accepting options on methods like segment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With my latest change they will get a warning if there are multiple options objects. I think that what you are suggesting is a good idea for a future PR. But for now this one should be good to go as-is!

# Conflicts:
#	src/BodyPix/index.js
#	src/FaceApi/index.js
#	src/Facemesh/index.js
#	src/Handpose/index.js
@lindapaiste lindapaiste requested a review from joeyklee May 8, 2022 19:25

return callCallback(this.segmentWithPartsInternal(imgToSegment, segmentationOptions), callback);

return callCallback(this.segmentWithPartsInternal(image, options), callback);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Positive affirmation:

  • 🧹 ✨ !!!

return callback ? instance : instance.ready;
const bodyPix = (...inputs) => {
const args = handleArguments(...inputs);
const instance = new BodyPix(args.video, args.options || {}, args.callback);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Positive affirmation

  • 🤩 digging this!

let model = string;
// TODO: I think we should delete this.
if (model.indexOf("http") === -1) {
model = model.toLowerCase();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good note:

  • Maybe we keep this in for now, but let's do a follow up at some point reassessing the model name handling. I feel like we talked about these somewhere? 😂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I created an issue #1339 but then I closed it because I interpreted the if statement backwards 🤦🏻‍♀️. I still think it should be handled a bit differently, but agreed that we should address it separately. I think I changed the one in ImageClassifier in #1362

modelName = 'model';
}
const { string, callback } = handleArguments(nameOrCb, cb);
const modelName = string || 'model';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonblocking comment:

  • handleArguements() feels like some kind of super hero magic -- "with great power comes great responsibility" 😂


// const PATH_START_LARGE = 'https://storage.googleapis.com/quickdraw-models/sketchRNN/large_models/';
// const PATH_START_SMALL = 'https://storage.googleapis.com/quickdraw-models/sketchRNN/models/';
// const PATH_END = '.gen.json';


const DEFAULTS = {
// TODO: this doesn't look right... -Linda
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonblocking comment:

  • Oh weird! Hmm seems like we might add this to another follow up to resolve. 🙈


this.config = {
temperature: 0.65,
pixelFactor: 3.0,
// TODO: it doesn't make sense for these to be instance properties -Linda
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nonblocking comment:

  • Agreed! Let's circle back around to this cleanup work.

*/
export default function handleArguments(...args) {
return new ArgHelper(...args);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Positive Affirmation:

  • Very clever + makes argument handling so much cleaner! Bravo! 🌟

Copy link
Contributor

@joeyklee joeyklee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such a long needed overhaul and cleanup of this major part of ml5. Thanks so much! 🏅

@joeyklee joeyklee added SEMVER/patch a version tag for a patch release change ready for release labels May 11, 2022
@lindapaiste lindapaiste merged commit b6fd7eb into ml5js:main May 12, 2022
@lindapaiste lindapaiste deleted the cleanup/handle-arguments branch May 12, 2022 17:58
joeyklee added a commit that referenced this pull request May 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready for release SEMVER/patch a version tag for a patch release change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants