diff --git a/mediapipe/examples/android/solutions/posetracking-lindera/src/main/BUILD b/mediapipe/examples/android/solutions/posetracking-lindera/src/main/BUILD
index 3bd9f445f..748ab157d 100644
--- a/mediapipe/examples/android/solutions/posetracking-lindera/src/main/BUILD
+++ b/mediapipe/examples/android/solutions/posetracking-lindera/src/main/BUILD
@@ -20,6 +20,7 @@ android_binary(
name = "posetracking-lindera",
srcs = glob(["**/*.java"]),
custom_package = "com.google.mediapipe.examples.posetracking_lindera",
+ dex_shards = 10,
manifest = "AndroidManifest.xml",
manifest_values = {
"applicationId": "com.google.mediapipe.examples.posetracking_lindera",
diff --git a/mediapipe/examples/android/solutions/posetracking-lindera/src/main/java/com/google/mediapipe/examples/posetracking_lindera/ComputerVisionPluginImpl.java b/mediapipe/examples/android/solutions/posetracking-lindera/src/main/java/com/google/mediapipe/examples/posetracking_lindera/ComputerVisionPluginImpl.java
index 88d1e0f45..705a1a699 100644
--- a/mediapipe/examples/android/solutions/posetracking-lindera/src/main/java/com/google/mediapipe/examples/posetracking_lindera/ComputerVisionPluginImpl.java
+++ b/mediapipe/examples/android/solutions/posetracking-lindera/src/main/java/com/google/mediapipe/examples/posetracking_lindera/ComputerVisionPluginImpl.java
@@ -1,5 +1,7 @@
package com.google.mediapipe.examples.posetracking_lindera;
+import static java.lang.Math.min;
+
import com.google.mediapipe.solutions.lindera.BodyJoints;
import com.google.mediapipe.solutions.lindera.ComputerVisionPlugin;
import com.google.mediapipe.solutions.lindera.XYZPointWithConfidence;
@@ -9,8 +11,10 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Field;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.Locale;
+import java.util.Map;
public class ComputerVisionPluginImpl implements ComputerVisionPlugin {
@@ -76,6 +80,18 @@ public class ComputerVisionPluginImpl implements ComputerVisionPlugin {
}
}
abbrev = abbrev.toUpperCase(Locale.ROOT);
+ // correct abbreviations here
+ switch (abbrev) {
+ case "P":
+ abbrev = "PE";
+ break;
+ case "T":
+ abbrev = "TH";
+ break;
+ case "S":
+ abbrev = "SP";
+ break;
+ }
XYZPointWithConfidence data = (XYZPointWithConfidence) field.get(bodyJoints);
assert data != null;
bodyJointsString = bodyJointsString.concat(String.format(abbrev+":%f,%f,%f=",data.x,data.y,data.z));
@@ -102,8 +118,14 @@ public class ComputerVisionPluginImpl implements ComputerVisionPlugin {
}
+
+
+
+
+
+
@Override
- public void bodyJoints(int timestamp, BodyJoints bodyJoints) {
+ public void bodyJoints(long timestamp, BodyJoints bodyJoints) {
if (isLogging){
this.bodyJointsEventList.add(new BodyJointsEvent(timestamp,bodyJoints));
diff --git a/mediapipe/examples/android/solutions/posetracking-lindera/src/main/java/com/google/mediapipe/examples/posetracking_lindera/MainActivity.java b/mediapipe/examples/android/solutions/posetracking-lindera/src/main/java/com/google/mediapipe/examples/posetracking_lindera/MainActivity.java
index a39a50013..3cd14ab9a 100644
--- a/mediapipe/examples/android/solutions/posetracking-lindera/src/main/java/com/google/mediapipe/examples/posetracking_lindera/MainActivity.java
+++ b/mediapipe/examples/android/solutions/posetracking-lindera/src/main/java/com/google/mediapipe/examples/posetracking_lindera/MainActivity.java
@@ -83,7 +83,7 @@ public class MainActivity extends AppCompatActivity {
findViewById(R.id.button_set_model).setVisibility(View.GONE);
findViewById(R.id.button_toggle_landmarks).setVisibility(View.GONE);
- findViewById(R.id.button_start_capture).setVisibility(View.GONE);
+ findViewById(R.id.button_capture_logging).setVisibility(View.GONE);
setupLiveDemoUiComponents();
plugin = new ComputerVisionPluginImpl();
@@ -116,7 +116,7 @@ public class MainActivity extends AppCompatActivity {
Button startDetectionButton = findViewById(R.id.button_start_detection);
Button toggleLandmarks = findViewById(R.id.button_toggle_landmarks);
Button modelComplexity = findViewById(R.id.button_set_model);
- Button startCapture = findViewById(R.id.button_start_capture);
+ Button startCapture = findViewById(R.id.button_capture_logging);
FrameLayout frameLayout = findViewById(R.id.preview_display_layout);
startDetectionButton.setOnClickListener(
@@ -129,7 +129,7 @@ public class MainActivity extends AppCompatActivity {
startDetectionButton.setVisibility(View.GONE);
findViewById(R.id.button_set_model).setVisibility(View.VISIBLE);
findViewById(R.id.button_toggle_landmarks).setVisibility(View.VISIBLE);
- findViewById(R.id.button_start_capture).setVisibility(View.VISIBLE);
+ findViewById(R.id.button_capture_logging).setVisibility(View.VISIBLE);
updateLandmarkButtonText();
updateModelComplexityButtonText();
diff --git a/mediapipe/examples/android/solutions/posetracking-lindera/src/main/res/layout/activity_main.xml b/mediapipe/examples/android/solutions/posetracking-lindera/src/main/res/layout/activity_main.xml
index 84418b5b3..ba95a5142 100644
--- a/mediapipe/examples/android/solutions/posetracking-lindera/src/main/res/layout/activity_main.xml
+++ b/mediapipe/examples/android/solutions/posetracking-lindera/src/main/res/layout/activity_main.xml
@@ -1,5 +1,6 @@
+ android:gravity="center"
+ android:orientation="horizontal">
+ android:text="Landmarks" />
+ android:text="Model" />
-
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:orientation="horizontal">
+
+
+
+
+
+
+ android:textSize="30sp"
+ android:textStyle="bold"
+ android:layout_marginTop="20dp"
+ android:layout_marginLeft="20dp"
+ android:elevation="10dp"
+ android:gravity="center_horizontal|center_vertical"/>
+
+
diff --git a/mediapipe/java/com/google/mediapipe/solutioncore/SolutionGlSurfaceViewRenderer.java b/mediapipe/java/com/google/mediapipe/solutioncore/SolutionGlSurfaceViewRenderer.java
index 47f7695ae..4f13973d5 100644
--- a/mediapipe/java/com/google/mediapipe/solutioncore/SolutionGlSurfaceViewRenderer.java
+++ b/mediapipe/java/com/google/mediapipe/solutioncore/SolutionGlSurfaceViewRenderer.java
@@ -49,6 +49,9 @@ public class SolutionGlSurfaceViewRenderer
public void setSolutionResultRenderer(ResultGlRenderer resultGlRenderer) {
this.resultGlRenderer = resultGlRenderer;
}
+ public ResultGlRenderer getSolutionResultRenderer(){
+ return this.resultGlRenderer;
+ }
/**
* Sets the next input {@link TextureFrame} and solution result to render.
diff --git a/mediapipe/java/com/google/mediapipe/solutions/lindera/BodyJoints.java b/mediapipe/java/com/google/mediapipe/solutions/lindera/BodyJoints.java
index e2addd572..81b5c3946 100644
--- a/mediapipe/java/com/google/mediapipe/solutions/lindera/BodyJoints.java
+++ b/mediapipe/java/com/google/mediapipe/solutions/lindera/BodyJoints.java
@@ -1,7 +1,7 @@
package com.google.mediapipe.solutions.lindera;
public class BodyJoints {
- public XYZPointWithConfidence nose;
+ public XYZPointWithConfidence neckNose;
public XYZPointWithConfidence leftEyeInner;
public XYZPointWithConfidence leftEye;
@@ -52,16 +52,15 @@ public class BodyJoints {
public XYZPointWithConfidence leftFoot;
-// public XYZPointWithConfidence pelvis;
-//
-// public XYZPointWithConfidence spine;
-// public XYZPointWithConfidence thorax;
-// public XYZPointWithConfidence neckNose;
-// public XYZPointWithConfidence headTop;
+ public XYZPointWithConfidence pelvis;
+
+ public XYZPointWithConfidence spine;
+ public XYZPointWithConfidence thorax;
+ public XYZPointWithConfidence headTop;
public BodyJoints() {
- nose = new XYZPointWithConfidence();
+ neckNose = new XYZPointWithConfidence();
leftEyeInner= new XYZPointWithConfidence();
leftEye= new XYZPointWithConfidence();
@@ -111,5 +110,10 @@ public class BodyJoints {
rightFoot= new XYZPointWithConfidence();
leftFoot= new XYZPointWithConfidence();
+ pelvis = new XYZPointWithConfidence();
+ spine = new XYZPointWithConfidence();
+ thorax = new XYZPointWithConfidence();
+ headTop = new XYZPointWithConfidence();
+
}
}
\ No newline at end of file
diff --git a/mediapipe/java/com/google/mediapipe/solutions/lindera/Lindera.java b/mediapipe/java/com/google/mediapipe/solutions/lindera/Lindera.java
index 6c50210c3..3e861efec 100644
--- a/mediapipe/java/com/google/mediapipe/solutions/lindera/Lindera.java
+++ b/mediapipe/java/com/google/mediapipe/solutions/lindera/Lindera.java
@@ -33,6 +33,7 @@ public class Lindera {
private CameraInput.CameraFacing cameraFacing = CameraInput.CameraFacing.FRONT;
private AppCompatActivity appCompatActivity;
private ViewGroup computerVisionContainerView;
+ private PoseTrackingResultGlRenderer solutionRenderer;
public Lindera(ComputerVisionPlugin plugin){
this.plugin = plugin;
@@ -41,6 +42,8 @@ public class Lindera {
public void setLandmarksVisibility(boolean visible){
this.poseTracking.options = PoseTrackingOptions.builder().withPoseTrackingOptions(this.poseTracking
.options).setLandmarkVisibility(visible).build();
+ solutionRenderer.setLandmarksVisibility(this.poseTracking.options.landmarkVisibility());
+ glSurfaceView.setSolutionResultRenderer(solutionRenderer);
}
public boolean getLandmarkVisibility(){
return this.poseTracking.options.landmarkVisibility();
@@ -150,7 +153,9 @@ public class Lindera {
poseTracking.getGlContext(),
poseTracking.getGlMajorVersion()
);
- glSurfaceView.setSolutionResultRenderer(new PoseTrackingResultGlRenderer());
+ solutionRenderer = new PoseTrackingResultGlRenderer();
+ solutionRenderer.setLandmarksVisibility(this.poseTracking.options.landmarkVisibility());
+ glSurfaceView.setSolutionResultRenderer(solutionRenderer);
glSurfaceView.setRenderInputImage(true);
setupEventListener();
@@ -184,10 +189,12 @@ public class Lindera {
bodyJoint.y = landmark.getY();
bodyJoint.z = landmark.getZ();
bodyJoint.confidence = landmark.getVisibility();
+ bodyJoint.presence = landmark.getPresence();
+
}
private void landmarksToBodyJoints(ImmutableList landmarks , BodyJoints bodyJoints){
- landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.NOSE), bodyJoints.nose);
+ landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.NOSE), bodyJoints.neckNose);
landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.LEFT_EYE_INNER), bodyJoints.leftEyeInner);
landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.LEFT_EYE), bodyJoints.leftEye);
@@ -236,6 +243,16 @@ public class Lindera {
landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.RIGHT_FOOT), bodyJoints.rightFoot);
landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.LEFT_FOOT), bodyJoints.leftFoot);
+
+ // additional points
+ landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.PELVIS), bodyJoints.pelvis);
+ landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.SPINE), bodyJoints.spine);
+ landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.THORAX), bodyJoints.thorax);
+ landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.HEAD_TOP), bodyJoints.headTop);
+
+
+
+
}
private void startCamera() {
diff --git a/mediapipe/java/com/google/mediapipe/solutions/lindera/XYZPointWithConfidence.java b/mediapipe/java/com/google/mediapipe/solutions/lindera/XYZPointWithConfidence.java
index 576f8f489..ac368d60c 100644
--- a/mediapipe/java/com/google/mediapipe/solutions/lindera/XYZPointWithConfidence.java
+++ b/mediapipe/java/com/google/mediapipe/solutions/lindera/XYZPointWithConfidence.java
@@ -5,6 +5,7 @@ public class XYZPointWithConfidence {
public float y = 0;
public float z = 0;
public float confidence = 0;
+ public float presence = 0;
diff --git a/mediapipe/java/com/google/mediapipe/solutions/posetracking/PoseTrackingResult.java b/mediapipe/java/com/google/mediapipe/solutions/posetracking/PoseTrackingResult.java
index 46dc45f90..0106893df 100644
--- a/mediapipe/java/com/google/mediapipe/solutions/posetracking/PoseTrackingResult.java
+++ b/mediapipe/java/com/google/mediapipe/solutions/posetracking/PoseTrackingResult.java
@@ -14,16 +14,21 @@
package com.google.mediapipe.solutions.posetracking;
+import static java.lang.Math.min;
+
import android.graphics.Bitmap;
+
import com.google.auto.value.AutoBuilder;
import com.google.common.collect.ImmutableList;
+import com.google.mediapipe.formats.proto.DetectionProto.Detection;
import com.google.mediapipe.formats.proto.LandmarkProto;
import com.google.mediapipe.framework.Packet;
import com.google.mediapipe.framework.TextureFrame;
import com.google.mediapipe.solutioncore.ImageSolutionResult;
-import com.google.mediapipe.formats.proto.DetectionProto.Detection;
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
/**
@@ -32,80 +37,157 @@ import java.util.List;
* the corresponding input image.
*/
public class PoseTrackingResult extends ImageSolutionResult {
- private final ImmutableList multiPoseDetections;
- private final ImmutableList multiPoseLandmarks;
-
- public static final int NOSE = 0;
- public static final int LEFT_EYE_INNER = 1;
- public static final int LEFT_EYE = 2;
- public static final int LEFT_EYE_OUTER = 3;
- public static final int RIGHT_EYE_INNER = 4;
- public static final int RIGHT_EYE = 5;
- public static final int RIGHT_EYE_OUTER = 6;
- public static final int LEFT_EAR = 7;
- public static final int RIGHT_EAR = 8;
- public static final int MOUTH_LEFT = 9;
- public static final int MOUTH_RIGHT = 10;
- public static final int LEFT_SHOULDER = 11;
- public static final int RIGHT_SHOULDER = 12;
- public static final int LEFT_ELBOW = 13;
- public static final int RIGHT_ELBOW = 14;
- public static final int LEFT_WRIST = 15;
- public static final int RIGHT_WRIST = 16;
- public static final int LEFT_PINKY = 17;
- public static final int RIGHT_PINKY = 18;
- public static final int LEFT_INDEX = 19;
- public static final int RIGHT_INDEX = 20;
- public static final int LEFT_THUMB = 21;
- public static final int RIGHT_THUMB = 22;
- public static final int LEFT_HIP = 23;
- public static final int RIGHT_HIP = 24;
- public static final int LEFT_KNEE = 25;
- public static final int RIGHT_KNEE = 26;
- public static final int LEFT_ANKLE = 27;
- public static final int RIGHT_ANKLE = 28;
- public static final int LEFT_HEEL = 29;
- public static final int RIGHT_HEEL = 30;
- public static final int LEFT_FOOT = 31;
- public static final int RIGHT_FOOT = 32;
+ private final ImmutableList multiPoseDetections;
+ private final ImmutableList multiPoseLandmarks;
- PoseTrackingResult(
- ImmutableList multiPoseDetections,ImmutableList multiPoseLandmarks, Packet imagePacket, long timestamp) {
- this.multiPoseDetections = multiPoseDetections;
- this.multiPoseLandmarks = multiPoseLandmarks;
- this.timestamp = timestamp;
- this.imagePacket = imagePacket;
- }
+ public static final int NOSE = 0;
+ public static final int LEFT_EYE_INNER = 1;
+ public static final int LEFT_EYE = 2;
+ public static final int LEFT_EYE_OUTER = 3;
+ public static final int RIGHT_EYE_INNER = 4;
+ public static final int RIGHT_EYE = 5;
+ public static final int RIGHT_EYE_OUTER = 6;
+ public static final int LEFT_EAR = 7;
+ public static final int RIGHT_EAR = 8;
+ public static final int MOUTH_LEFT = 9;
+ public static final int MOUTH_RIGHT = 10;
+ public static final int LEFT_SHOULDER = 11;
+ public static final int RIGHT_SHOULDER = 12;
+ public static final int LEFT_ELBOW = 13;
+ public static final int RIGHT_ELBOW = 14;
+ public static final int LEFT_WRIST = 15;
+ public static final int RIGHT_WRIST = 16;
+ public static final int LEFT_PINKY = 17;
+ public static final int RIGHT_PINKY = 18;
+ public static final int LEFT_INDEX = 19;
+ public static final int RIGHT_INDEX = 20;
+ public static final int LEFT_THUMB = 21;
+ public static final int RIGHT_THUMB = 22;
+ public static final int LEFT_HIP = 23;
+ public static final int RIGHT_HIP = 24;
+ public static final int LEFT_KNEE = 25;
+ public static final int RIGHT_KNEE = 26;
+ public static final int LEFT_ANKLE = 27;
+ public static final int RIGHT_ANKLE = 28;
+ public static final int LEFT_HEEL = 29;
+ public static final int RIGHT_HEEL = 30;
+ public static final int LEFT_FOOT = 31;
+ public static final int RIGHT_FOOT = 32;
- // Collection of detected faces, where each face is represented as a detection proto message that
- // contains a bounding box and 6 {@link FaceKeypoint}s. The bounding box is composed of xmin and
- // width (both normalized to [0.0, 1.0] by the image width) and ymin and height (both normalized
- // to [0.0, 1.0] by the image height). Each keypoint is composed of x and y, which are normalized
- // to [0.0, 1.0] by the image width and height respectively.
- public ImmutableList multiPoseTrackings() {
- return multiPoseDetections;
- }
+ // Additional points not provided by MediaPipe
+ public static final int PELVIS = 33;
+ public static final int SPINE = 34;
+ public static final int THORAX = 35;
+ public static final int HEAD_TOP = 36;
- public ImmutableList multiPoseLandmarks() {
- return multiPoseLandmarks;
- }
+ PoseTrackingResult(
+ ImmutableList multiPoseDetections, ImmutableList multiPoseLandmarks, Packet imagePacket, long timestamp) {
+ this.multiPoseDetections = multiPoseDetections;
+ this.multiPoseLandmarks = multiPoseLandmarks;
+ this.timestamp = timestamp;
+ this.imagePacket = imagePacket;
+ }
- public static Builder builder() {
- return new AutoBuilder_PoseTrackingResult_Builder();
- }
+ // Collection of detected faces, where each face is represented as a detection proto message that
+ // contains a bounding box and 6 {@link FaceKeypoint}s. The bounding box is composed of xmin and
+ // width (both normalized to [0.0, 1.0] by the image width) and ymin and height (both normalized
+ // to [0.0, 1.0] by the image height). Each keypoint is composed of x and y, which are normalized
+ // to [0.0, 1.0] by the image width and height respectively.
+ public ImmutableList multiPoseTrackings() {
+ return multiPoseDetections;
+ }
- /** Builder for {@link PoseTrackingResult}. */
- @AutoBuilder
- public abstract static class Builder {
- abstract Builder setMultiPoseDetections(List value);
- abstract Builder setMultiPoseLandmarks(List value);
+ static LandmarkProto.Landmark getJointBetweenPoints(LandmarkProto.Landmark pt1, LandmarkProto.Landmark pt2, float distance) {
+ return LandmarkProto.Landmark.newBuilder()
+ .setX(pt1.getX() + (pt2.getX() - pt1.getX()) * distance)
+ .setY(pt1.getY() + (pt2.getY() - pt1.getY()) * distance)
+ .setZ(pt1.getZ() + (pt2.getZ() - pt1.getZ()) * distance)
+ .setPresence(min(pt1.getPresence(), pt2.getPresence()))
+ .setVisibility(min(pt1.getVisibility(), pt2.getVisibility())).build();
+ }
- abstract Builder setTimestamp(long value);
+ LandmarkProto.Landmark getPelvis(ImmutableList landmarks) {
+ // middle point b/w left hip and right hip
+ return getJointBetweenPoints(landmarks.get(LEFT_HIP), landmarks.get(RIGHT_HIP), 0.5f);
+ }
- abstract Builder setImagePacket(Packet value);
+ LandmarkProto.Landmark getSpinePoint(ImmutableList landmarks, float distanceFromShoulders) {
+ LandmarkProto.Landmark pelvis = getPelvis(landmarks);
+ // middle point b/w left shoulder and right shoulder
+ LandmarkProto.Landmark chest = getJointBetweenPoints(landmarks.get(LEFT_SHOULDER), landmarks.get(RIGHT_SHOULDER), 0.5f);
- abstract PoseTrackingResult build();
- }
+ return getJointBetweenPoints(chest, pelvis, distanceFromShoulders);
+ }
+
+ LandmarkProto.Landmark getHeadTop(ImmutableList landmarks) {
+
+ float x = 0;
+ float y = 0;
+ float z = 0;
+ float confidence = 1;
+ float presence = 1;
+ final List ptsIdx = Arrays.asList(LEFT_EAR, LEFT_EYE, RIGHT_EYE, RIGHT_EAR);
+ for (Integer i :ptsIdx){
+ LandmarkProto.Landmark landmark = landmarks.get(i);
+ x+=landmark.getX();
+ y+=landmark.getY();
+ z+=landmark.getZ();
+ presence = min(presence,landmark.getPresence());
+ confidence = min(confidence,landmark.getVisibility());
+ }
+ x = x/ptsIdx.size();
+ y = y/ptsIdx.size();
+ z = z/ptsIdx.size();
+ LandmarkProto.Landmark midupper = LandmarkProto.Landmark.newBuilder().setX(x).setY(y).setZ(z)
+ .setVisibility(confidence).setPresence(presence).build();
+
+
+ LandmarkProto.Landmark midlower = getJointBetweenPoints(landmarks.get(MOUTH_LEFT), landmarks.get(MOUTH_RIGHT), 0.5f);
+ // 2 times the distance b/w nose and eyes
+ return getJointBetweenPoints(midlower, midupper, 2.5f);
+ }
+
+ ImmutableList getAdditionalLandmarksByInterpolation(ImmutableList originalLandmarks) {
+
+ if (originalLandmarks.isEmpty()) return originalLandmarks;
+ List landmarks = new ArrayList<>(originalLandmarks);
+ // pelvis
+ landmarks.add(getPelvis(originalLandmarks));
+ // spine assuming it is 2/3rd of distance b/w shoulders and pelvis
+ landmarks.add(getSpinePoint(originalLandmarks, 2 / 3f));
+ // thorax assuming it is 1/3rd of distance b/w shoulders and pelvis
+ landmarks.add(getSpinePoint(originalLandmarks, 1 / 3f));
+ // head top
+ landmarks.add(getHeadTop(originalLandmarks));
+
+
+ return ImmutableList.copyOf(landmarks);
+
+ }
+
+ public ImmutableList multiPoseLandmarks() {
+ return getAdditionalLandmarksByInterpolation(multiPoseLandmarks);
+ }
+
+ public static Builder builder() {
+ return new AutoBuilder_PoseTrackingResult_Builder();
+ }
+
+ /**
+ * Builder for {@link PoseTrackingResult}.
+ */
+ @AutoBuilder
+ public abstract static class Builder {
+ abstract Builder setMultiPoseDetections(List value);
+
+ abstract Builder setMultiPoseLandmarks(List value);
+
+ abstract Builder setTimestamp(long value);
+
+ abstract Builder setImagePacket(Packet value);
+
+ abstract PoseTrackingResult build();
+ }
}
diff --git a/mediapipe/java/com/google/mediapipe/solutions/posetracking/PoseTrackingResultGlRenderer.java b/mediapipe/java/com/google/mediapipe/solutions/posetracking/PoseTrackingResultGlRenderer.java
index a74898f3d..b85e21420 100644
--- a/mediapipe/java/com/google/mediapipe/solutions/posetracking/PoseTrackingResultGlRenderer.java
+++ b/mediapipe/java/com/google/mediapipe/solutions/posetracking/PoseTrackingResultGlRenderer.java
@@ -16,13 +16,17 @@ package com.google.mediapipe.solutions.posetracking;
import android.opengl.GLES20;
+import com.google.common.collect.ImmutableList;
import com.google.mediapipe.formats.proto.DetectionProto.Detection;
+import com.google.mediapipe.formats.proto.LandmarkProto;
import com.google.mediapipe.solutioncore.ResultGlRenderer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
-
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/** A custom implementation of {@link ResultGlRenderer} to render {@link PoseTrackingResult}. */
@@ -52,7 +56,10 @@ public class PoseTrackingResultGlRenderer implements ResultGlRenderer originalLandmarks = result.multiPoseLandmarks();
+ List landmarks = originalLandmarks.stream().filter((landmark -> {
+ return landmark.getVisibility() > 0.25 || landmark.getPresence()>0.25;
+ })).collect(Collectors.toList());
+
+
+ // Draw keypoints.
+ float[] points = new float[landmarks.size() * 2];
+ for (int i = 0; i < landmarks.size(); ++i) {
+ points[2 * i] = landmarks.get(i).getX();
+ points[2 * i + 1] = 1-landmarks.get(i).getY();
+ }
+ GLES20.glUniform4fv(colorHandle, 1, KEYPOINT_COLOR, 0);
+ FloatBuffer vertexBuffer =
+ ByteBuffer.allocateDirect(points.length * 4)
+ .order(ByteOrder.nativeOrder())
+ .asFloatBuffer()
+ .put(points);
+ vertexBuffer.position(0);
+ GLES20.glEnableVertexAttribArray(positionHandle);
+ GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer);
+ GLES20.glDrawArrays(GLES20.GL_POINTS, 0, landmarks.size());
+
}
/**
@@ -100,6 +126,8 @@ public class PoseTrackingResultGlRenderer implements ResultGlRenderer