import {Color, Keypoint, MovementAnalyzer, Position} from "guru/stdlib";
export default class GuruSchema {
constructor() {
this.personFrames = [];
this.reps = [];
this.hipKneeAngles = [];
}
async processFrame(frame) {
const people = await frame.findObjects("person");
const person = people[0];
this.personFrames.push(person);
this.reps = MovementAnalyzer.repsByKeypointDistance(this.personFrames, Keypoint.rightHip, Keypoint.rightAnkle);
this.hipKneeAngles = this.reps.map((rep) => {
return MovementAnalyzer.angleBetweenKeypoints(rep.middleFrame, Keypoint.rightKnee, Keypoint.rightHip);
});
return this.outputs();
}
renderFrame(frameCanvas) {
if (this.personFrames.length > 0) {
frameCanvas.drawBoundingBox(this.personFrames, new Color(93, 236, 201));
frameCanvas.drawSkeleton(this.personFrames, new Color(97, 49, 255), new Color(255, 255, 255));
const person = this.personFrames.find((frameObject) => frameObject.timestamp >= frameCanvas.timestamp);
const kneeLocation = person.keypoints[Keypoint.rightKnee];
const hipLocation = person.keypoints[Keypoint.rightHip];
frameCanvas.drawTriangle(
kneeLocation,
hipLocation,
new Position(hipLocation.x, kneeLocation.y),
{
backgroundColor: new Color(93, 236, 201),
alpha: 0.75
}
);
if (this.reps && this.reps.length > 0) {
let repIndex = this.reps.findIndex((rep) => {
return frameCanvas.timestamp >= rep.startFrame.timestamp && frameCanvas.timestamp <= rep.endFrame.timestamp;
});
if (frameCanvas.timestamp > this.reps[this.reps.length - 1].endFrame.timestamp) {
repIndex = this.reps.length - 1;
}
if (repIndex >= 0) {
frameCanvas.drawText(`Rep ${repIndex + 1}`, new Position(0.1, 0.1), new Color(255, 255, 255), {
fontSize: 36,
backgroundColor: new Color(94, 49, 255),
padding: 4
});
const rep = this.reps[repIndex];
const repAlpha = 1.0 - Math.abs(rep.middleFrame.timestamp - frameCanvas.timestamp) / (rep.endFrame.timestamp - rep.startFrame.timestamp);
const hipKneeAngle = Math.round(this.hipKneeAngles[repIndex]);
const badForm = hipKneeAngle < -2;
frameCanvas.drawText(
`${hipKneeAngle}°`,
kneeLocation,
new Color(255, 255, 255),
{
fontSize: 36,
alpha: repAlpha,
backgroundColor: badForm ? new Color(232, 92, 92) : new Color(94, 49, 255),
padding: 4
}
);
if (badForm) {
frameCanvas.drawText(
`Get your hips lower`,
hipLocation,
new Color(255, 255, 255),
{
fontSize: 18,
alpha: repAlpha,
backgroundColor: new Color(232, 92, 92),
padding: 4
}
);
}
}
}
}
}
async outputs() {
return {
reps: this.reps,
hipKneeAngles: this.hipKneeAngles,
}
}
}