/** * 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); } }
/** * 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); }
@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); } }
@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(); }
@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(); }