public static final Collection<PointingRay3DFloat> getAllRaysForSideWithConfidence(final TrackedPosture3DFloat posture, final boolean right, final double pointingProbability) { return getAllRaysForSideAndTypesWithConfidence(posture, right, pointingProbability, Arrays.asList(PointingType.values())); }
public static final double getSignedHorizontalAngle(final TrackedPosture3DFloat posture, final boolean right, final boolean relative) { final Joints handJoint = right ? Joints.HandRight : Joints.HandLeft; final Point3D up = postureUpDirection(posture, relative); final Point3D front = postureFrontDirection(posture, up); final Point3D direction = projectOrthogonal(getDirection(posture, new JointPair(Joints.SpineMid, handJoint)), up); return getSignedAngle(front, direction, up); } }
public static final Point3D getDirection(final TrackedPosture3DFloat posture, final JointPair jointPair) { final Point3D start = getPoint3D(posture, jointPair.getJoint1()); final Point3D end = getPoint3D(posture, jointPair.getJoint2()); return end.subtract(start); }
/** * Does the same as pointingProbability except using a different model that lead to a higher AUC for the training data, but does not offer thresholds of a similar feasability. * * @param posture the observed posture. * @param right true, if the arm for which the probability is calculated is the right (not left) one. * @return The probability of the tracked person pointing with the specified arm calculated based on empirical data. */ private double pointingProbabilityHigherAUC(final TrackedPosture3DFloat posture, final boolean right) { final double elbowAngle = getElbowAngle(posture, right); final double handHeightAngle = getHandHeightAngle(posture, right, true); final double heightFactor = 0.5 + 0.5 * Math.tanh((107 - handHeightAngle) / 18); final double expectedElbowAngle = handHeightAngle >= 80 ? 180 : (handHeightAngle - 4) * 30 / 76 + 150; final double extension_factor = (new NormalDistribution(expectedElbowAngle, 40)).density(elbowAngle) * 100; return Math.min(heightFactor * extension_factor, 1.0) * PostureFunctions.postureConfidence(posture, right); } }
public static final double getElbowHeightAngle(final TrackedPosture3DFloat posture, final boolean right, final boolean relative) { final JointPair armJoints = right ? new JointPair(Joints.ShoulderRight, Joints.ElbowRight) : new JointPair(Joints.ShoulderLeft, Joints.ElbowLeft); final Point3D direction = getDirection(posture, armJoints); final Point3D up = postureUpDirection(posture, relative); return up.angle(direction); }
@Override public PointingRay3DFloatDistribution getRays(TrackedPosture3DFloat posture, boolean right, double pointingProbability) { double handHeightAngle = getHandHeightAngle(posture, right, false); Point3D hand = getPoint3D(posture, right ? Joints.HandRight : Joints.HandLeft); Point3D spineShoulder = getPoint3D(posture, Joints.SpineShoulder); Point3D spineHeadDirection = getPoint3D(posture, Joints.Head).subtract(spineShoulder); double factor = 0; final double[] parameters = getParameters(); for (int i = 0; i < parameters.length; i++) { factor += Math.pow(handHeightAngle, parameters.length - i - 1) * parameters[i]; } Point3D start = spineShoulder.add(spineHeadDirection.multiply(factor)); return PointingRay3DFloatDistribution.newBuilder().addRay(PointingRay3DFloat.newBuilder() .setType(PointingType.OTHER) .setRightHandPointing(right) .setCertainty((float) pointingProbability) .setRay(Ray3DFloatType.Ray3DFloat.newBuilder() .setOrigin(toVec3DFloat(hand)) .setDirection(toVec3DFloat(hand.subtract(start).normalize())) ) ).build(); }
public static final Point3D postureRightDirection(final TrackedPosture3DFloat posture, final Point3D up) { final Point3D hipDir = getDirection(posture, new JointPair(Joints.HipLeft, Joints.HipRight)); final Point3D shoulderDir = getDirection(posture, new JointPair(Joints.ShoulderLeft, Joints.ShoulderRight)); return projectOrthogonal(hipDir.add(shoulderDir.multiply(0.5)), up).normalize(); }
@Override public PointingRay3DFloatDistribution getRays(TrackedPosture3DFloat posture, boolean right, double pointingProbability) { double handHeightAngle = getHandHeightAngle(posture, right, false); return PointingRay3DFloatDistribution.newBuilder() .addRay(getPointingRay(posture, right, pointingProbability*getShoulderHandProb(handHeightAngle), PointingType.SHOULDER_HAND)) .addRay(getPointingRay(posture, right, pointingProbability*getHeadHandProb(handHeightAngle), PointingType.HEAD_HAND)) .addRay(getPointingRay(posture, right, pointingProbability*getElbowHandProb(handHeightAngle), PointingType.FOREARM)) .addRay(getPointingRay(posture, right, pointingProbability*getHandTipProb(handHeightAngle), PointingType.HAND)).build(); }
/** * Constructor. * * @param timestamp time of observation of the posture. * @param posture the tracked posture. * @param pointingProbabilityRight the base probability of a pointing gesture using the right arm. * @param pointingProbabilityLeft the base probability of a pointing gesture using the left arm. */ PostureHistoryEntry(final long timestamp, final TrackedPosture3DFloat posture, final double pointingProbabilityRight, final double pointingProbabilityLeft) { this.timestamp = timestamp; this.probabilityRight = pointingProbabilityRight; this.probabilityLeft = pointingProbabilityLeft; // this.head = PostureFunctions.getPoint3D(posture, Joints.Head); // this.shoulderRight = PostureFunctions.getPoint3D(posture, Joints.ShoulderRight); // this.shoulderLeft = PostureFunctions.getPoint3D(posture, Joints.ShoulderLeft); // this.elbowRight = PostureFunctions.getPoint3D(posture, Joints.ElbowRight); // this.elbowLeft = PostureFunctions.getPoint3D(posture, Joints.ElbowLeft); // this.handRight = PostureFunctions.getPoint3D(posture, Joints.HandRight); // this.handLeft = PostureFunctions.getPoint3D(posture, Joints.HandLeft); this.directionRight = PostureFunctions.getDirection(posture, new JointPair(Joints.ShoulderRight, Joints.HandRight)); this.directionLeft = PostureFunctions.getDirection(posture, new JointPair(Joints.ShoulderLeft, Joints.HandLeft)); }
public static final PointingRay3DFloat getPointingRay(final TrackedPosture3DFloat posture, final boolean right, final double pointingProbability, final PointingType type) { final JointPair jointPair = getJointPair(right, type); return PointingRay3DFloat.newBuilder().setRay(getRay(posture, jointPair)).setCertainty((float) pointingProbability).setType(type).setRightHandPointing(right).build(); }
@Override public PointingRay3DFloatDistribution getRays(TrackedPosture3DFloat posture, boolean right, double pointingProbability) { if (choice == null) { return PointingRay3DFloatDistribution.newBuilder().addAllRay(getAllRaysForSideWithConfidence(posture, right, pointingProbability)).build(); } return PointingRay3DFloatDistribution.newBuilder().addAllRay(getAllRaysForSideAndTypesWithConfidence(posture, right, pointingProbability, choice)).build(); }
public static final PointingRay3DFloat getPointingRayWithConfidence(final TrackedPosture3DFloat posture, final boolean right, final double pointingProbability, final PointingType type) { final JointPair jointPair = getJointPair(right, type); final float certainty = posture.getConfidence(jointPair.getJoint1().getValue()) * posture.getConfidence(jointPair.getJoint2().getValue()); return getPointingRay(posture, right, certainty * pointingProbability, type); }
@Override public PointingRay3DFloatDistributionType.PointingRay3DFloatDistribution getRays(TrackedPosture3DFloat posture, boolean right, double pointingProbability) { double handHeightAngle = getHandHeightAngle(posture, right, false); if(MIN_NECK_ANGLE < handHeightAngle && handHeightAngle < MAX_NECK_ANGLE){ JointPair jointPair = new JointPair(Joints.Neck, right ? Joints.HandRight: Joints.HandLeft); return PointingRay3DFloatDistribution.newBuilder().addRay(PointingRay3DFloat.newBuilder() .setType(PointingType.OTHER) .setRightHandPointing(right) .setCertainty((float)pointingProbability) .setRay(getRay(posture, jointPair)) ).build(); } return polySelector.getRays(posture, right, pointingProbability); } }
public Joint3D(Translation translation, double confidence) { this.translation = translation; this.position = PostureFunctions.toPoint3D(translation); this.confidence = confidence; }
public static final boolean checkConfidences(final TrackedPosture3DFloat posture, final boolean right) { return postureConfidence(posture, right) == 1.0; }
public static final Vec3DFloat getVec(final TrackedPosture3DFloat posture, final Joints joint) { return toVec3DFloat(posture.getPosture().getPosition(joint.getValue())); }
/** * * {@inheritDoc} * * @return {@inheritDoc} * @throws NotAvailableException {@inheritDoc} */ @Override public synchronized List<PointingRay3DFloatDistribution> getPointingRays() throws NotAvailableException { if (lastPostures == null) { throw new NotAvailableException("Pointing Rays"); } return lastPostures.getPostureList().stream() .filter(posture -> checkPosture(posture)) .map(posture -> getRays(posture, 1, 1)) .flatMap(List::stream) .collect(Collectors.toList()); } }
/** * Returns the overall probability that the observed posture is performing a pointing the gesture on the specified side. * * @param posture the observed posture. * @param right true, if the arm for which the probability is calculated is the right (not left) one. * @return The probability of the tracked person pointing with the specified arm calculated based on empirical data. */ public static double pointingProbability(final TrackedPosture3DFloat posture, final boolean right) { //Recommended threshold: 0.3/0.4 final double elbowAngle = getElbowAngle(posture, right); final double handHeightAngle = getHandHeightAngle(posture, right, false); final double heightFactor = 0.5 + 0.5 * Math.tanh((140 - handHeightAngle) / 20); final double expectedElbowAngle = handHeightAngle >= 60 ? 180 : (handHeightAngle - 20) * 0.75 + 150; final double extension_factor = (new NormalDistribution(expectedElbowAngle, 40)).density(elbowAngle) * 100; return Math.min(heightFactor * extension_factor, 1.0) * PostureFunctions.postureConfidence(posture, right); }
public static final double getHandHeightAngle(final TrackedPosture3DFloat posture, final boolean right, final boolean relative) { final JointPair armJoints = right ? new JointPair(Joints.ShoulderRight, Joints.HandRight) : new JointPair(Joints.ShoulderLeft, Joints.HandLeft); final Point3D direction = getDirection(posture, armJoints); final Point3D up = postureUpDirection(posture, relative); return up.angle(direction); }
public static final Point3D postureUpDirection(final TrackedPosture3DFloat posture) { return getDirection(posture, new JointPair(Joints.SpineBase, Joints.Neck)).normalize(); }