added interpolation with visualization

This commit is contained in:
Mautisim Munir 2022-10-28 19:51:05 +05:00
parent e2884bc21f
commit be07542ef7
9 changed files with 246 additions and 160 deletions

View File

@ -20,6 +20,7 @@ android_binary(
name = "posetracking-lindera", name = "posetracking-lindera",
srcs = glob(["**/*.java"]), srcs = glob(["**/*.java"]),
custom_package = "com.google.mediapipe.examples.posetracking_lindera", custom_package = "com.google.mediapipe.examples.posetracking_lindera",
dex_shards = 10,
manifest = "AndroidManifest.xml", manifest = "AndroidManifest.xml",
manifest_values = { manifest_values = {
"applicationId": "com.google.mediapipe.examples.posetracking_lindera", "applicationId": "com.google.mediapipe.examples.posetracking_lindera",

View File

@ -88,7 +88,6 @@ public class ComputerVisionPluginImpl implements ComputerVisionPlugin {
} }
} }
bodyJointsString = bodyJointsString.concat(interpolateJoints(bodyJoints));
// remove the last equal sign // remove the last equal sign
bodyJointsString = bodyJointsString.substring(0,bodyJointsString.length()-1); bodyJointsString = bodyJointsString.substring(0,bodyJointsString.length()-1);
@ -106,68 +105,11 @@ public class ComputerVisionPluginImpl implements ComputerVisionPlugin {
} }
String interpolateJoints(BodyJoints bodyJoints){
Map<String,XYZPointWithConfidence> pts = new HashMap<>();
pts.put("PE", getPelvis(bodyJoints));
pts.put("NN",bodyJoints.nose);
// Assuming Thorax is 1/3 of distance between shoulders and pelvis
XYZPointWithConfidence thorax = getSpinePoint(bodyJoints,1/3f);
// Assuming spine/middle back is 2/3 of distance between shoulders and pelvis
XYZPointWithConfidence spine = getSpinePoint(bodyJoints,2/3f);
pts.put("TH",thorax);
pts.put("SP",spine);
pts.put("HT",getHeadTop(bodyJoints));
final String[] bodyJointsString = {""};
pts.forEach((key,data)->{
bodyJointsString[0] = bodyJointsString[0].concat(String.format(key+":%f,%f,%f=",data.x,data.y,data.z));
});
return bodyJointsString[0];
}
XYZPointWithConfidence getPelvis(BodyJoints bodyJoints){
return getMiddleJoint(bodyJoints.leftHip,bodyJoints.rightHip);
}
XYZPointWithConfidence getJointBetweenPoints(XYZPointWithConfidence pt1,XYZPointWithConfidence pt2,float distance){
XYZPointWithConfidence midpt = new XYZPointWithConfidence();
midpt.x = pt1.x + (pt2.x-pt1.x)*distance;
midpt.y = pt1.y + (pt2.y-pt1.y)*distance;
midpt.z = pt1.z + (pt2.z-pt1.z)*distance;
midpt.presence = min(pt1.presence,pt2.presence);
midpt.confidence = min(pt1.confidence,pt2.confidence);
return midpt;
}
XYZPointWithConfidence getMiddleJoint(XYZPointWithConfidence pt1,XYZPointWithConfidence pt2) {
XYZPointWithConfidence midpt = new XYZPointWithConfidence();
midpt.x = (pt1.x + pt2.x)/2;
midpt.y = (pt1.y + pt2.y)/2;
midpt.z = (pt1.z + pt2.z)/2;
midpt.presence = min(pt1.presence,pt2.presence);
midpt.confidence = min(pt1.confidence,pt2.confidence);
return midpt;
}
XYZPointWithConfidence getSpinePoint(BodyJoints bodyJoints, float distanceFromShoulders){
XYZPointWithConfidence midShoulder = getMiddleJoint(bodyJoints.leftShoulder, bodyJoints.rightShoulder);
XYZPointWithConfidence pelvis = getPelvis(bodyJoints);
return getJointBetweenPoints(midShoulder,pelvis,distanceFromShoulders);
}
XYZPointWithConfidence getHeadTop(BodyJoints bodyJoints){
XYZPointWithConfidence middleEye = getMiddleJoint(bodyJoints.leftEye,bodyJoints.rightEye);
return getJointBetweenPoints(middleEye,bodyJoints.nose,2);
}
@Override @Override

View File

@ -83,7 +83,7 @@ public class MainActivity extends AppCompatActivity {
findViewById(R.id.button_set_model).setVisibility(View.GONE); findViewById(R.id.button_set_model).setVisibility(View.GONE);
findViewById(R.id.button_toggle_landmarks).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(); setupLiveDemoUiComponents();
plugin = new ComputerVisionPluginImpl(); plugin = new ComputerVisionPluginImpl();
@ -116,7 +116,7 @@ public class MainActivity extends AppCompatActivity {
Button startDetectionButton = findViewById(R.id.button_start_detection); Button startDetectionButton = findViewById(R.id.button_start_detection);
Button toggleLandmarks = findViewById(R.id.button_toggle_landmarks); Button toggleLandmarks = findViewById(R.id.button_toggle_landmarks);
Button modelComplexity = findViewById(R.id.button_set_model); 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); FrameLayout frameLayout = findViewById(R.id.preview_display_layout);
startDetectionButton.setOnClickListener( startDetectionButton.setOnClickListener(
@ -129,7 +129,7 @@ public class MainActivity extends AppCompatActivity {
startDetectionButton.setVisibility(View.GONE); startDetectionButton.setVisibility(View.GONE);
findViewById(R.id.button_set_model).setVisibility(View.VISIBLE); findViewById(R.id.button_set_model).setVisibility(View.VISIBLE);
findViewById(R.id.button_toggle_landmarks).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(); updateLandmarkButtonText();
updateModelComplexityButtonText(); updateModelComplexityButtonText();

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -10,7 +11,8 @@
style="?android:attr/buttonBarStyle" style="?android:attr/buttonBarStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center"> android:gravity="center"
android:orientation="horizontal">
<Button <Button
android:id="@+id/button_start_detection" android:id="@+id/button_start_detection"
@ -24,28 +26,32 @@
style="?android:attr/buttonBarButtonStyle" style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Show Landmarks" /> android:text="Landmarks" />
<Button <Button
android:id="@+id/button_set_model" android:id="@+id/button_set_model"
style="?android:attr/buttonBarButtonStyle" style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Set Model" /> android:text="Model" />
<Button <Button
android:id="@+id/button_start_capture" android:id="@+id/button_capture_logging"
style="?android:attr/buttonBarButtonStyle" style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Start Capture" /> android:text="Start Capture" />
<TextView
android:id="@+id/fps_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout> </LinearLayout>
<FrameLayout
android:id="@+id/overlay"
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<FrameLayout <FrameLayout
android:id="@+id/preview_display_layout" android:id="@+id/preview_display_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -57,5 +63,20 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:text="@string/instruction" /> android:text="@string/instruction" />
</FrameLayout> </FrameLayout>
<TextView
android:id="@+id/fps_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:textStyle="bold"
android:layout_marginTop="20dp"
android:layout_marginLeft="20dp"
android:elevation="10dp"
android:gravity="center_horizontal|center_vertical"/>
</FrameLayout>
</LinearLayout> </LinearLayout>

View File

@ -49,6 +49,9 @@ public class SolutionGlSurfaceViewRenderer<T extends ImageSolutionResult>
public void setSolutionResultRenderer(ResultGlRenderer<T> resultGlRenderer) { public void setSolutionResultRenderer(ResultGlRenderer<T> resultGlRenderer) {
this.resultGlRenderer = resultGlRenderer; this.resultGlRenderer = resultGlRenderer;
} }
public ResultGlRenderer<T> getSolutionResultRenderer(){
return this.resultGlRenderer;
}
/** /**
* Sets the next input {@link TextureFrame} and solution result to render. * Sets the next input {@link TextureFrame} and solution result to render.

View File

@ -1,7 +1,7 @@
package com.google.mediapipe.solutions.lindera; package com.google.mediapipe.solutions.lindera;
public class BodyJoints { public class BodyJoints {
public XYZPointWithConfidence nose; public XYZPointWithConfidence neckNose;
public XYZPointWithConfidence leftEyeInner; public XYZPointWithConfidence leftEyeInner;
public XYZPointWithConfidence leftEye; public XYZPointWithConfidence leftEye;
@ -52,16 +52,15 @@ public class BodyJoints {
public XYZPointWithConfidence leftFoot; public XYZPointWithConfidence leftFoot;
// public XYZPointWithConfidence pelvis; public XYZPointWithConfidence pelvis;
//
// public XYZPointWithConfidence spine; public XYZPointWithConfidence spine;
// public XYZPointWithConfidence thorax; public XYZPointWithConfidence thorax;
// public XYZPointWithConfidence neckNose; public XYZPointWithConfidence headTop;
// public XYZPointWithConfidence headTop;
public BodyJoints() { public BodyJoints() {
nose = new XYZPointWithConfidence(); neckNose = new XYZPointWithConfidence();
leftEyeInner= new XYZPointWithConfidence(); leftEyeInner= new XYZPointWithConfidence();
leftEye= new XYZPointWithConfidence(); leftEye= new XYZPointWithConfidence();
@ -111,5 +110,10 @@ public class BodyJoints {
rightFoot= new XYZPointWithConfidence(); rightFoot= new XYZPointWithConfidence();
leftFoot= new XYZPointWithConfidence(); leftFoot= new XYZPointWithConfidence();
pelvis = new XYZPointWithConfidence();
spine = new XYZPointWithConfidence();
thorax = new XYZPointWithConfidence();
headTop = new XYZPointWithConfidence();
} }
} }

View File

@ -37,6 +37,7 @@ public class Lindera {
private CameraInput.CameraFacing cameraFacing = CameraInput.CameraFacing.FRONT; private CameraInput.CameraFacing cameraFacing = CameraInput.CameraFacing.FRONT;
private AppCompatActivity appCompatActivity; private AppCompatActivity appCompatActivity;
private ViewGroup computerVisionContainerView; private ViewGroup computerVisionContainerView;
private PoseTrackingResultGlRenderer solutionRenderer;
public Lindera(ComputerVisionPlugin plugin){ public Lindera(ComputerVisionPlugin plugin){
this.plugin = plugin; this.plugin = plugin;
@ -45,6 +46,8 @@ public class Lindera {
public void setLandmarksVisibility(boolean visible){ public void setLandmarksVisibility(boolean visible){
this.poseTracking.options = PoseTrackingOptions.builder().withPoseTrackingOptions(this.poseTracking this.poseTracking.options = PoseTrackingOptions.builder().withPoseTrackingOptions(this.poseTracking
.options).setLandmarkVisibility(visible).build(); .options).setLandmarkVisibility(visible).build();
solutionRenderer.setLandmarksVisibility(this.poseTracking.options.landmarkVisibility());
glSurfaceView.setSolutionResultRenderer(solutionRenderer);
} }
public boolean getLandmarkVisibility(){ public boolean getLandmarkVisibility(){
return this.poseTracking.options.landmarkVisibility(); return this.poseTracking.options.landmarkVisibility();
@ -154,7 +157,9 @@ public class Lindera {
poseTracking.getGlContext(), poseTracking.getGlContext(),
poseTracking.getGlMajorVersion() poseTracking.getGlMajorVersion()
); );
glSurfaceView.setSolutionResultRenderer(new PoseTrackingResultGlRenderer()); solutionRenderer = new PoseTrackingResultGlRenderer();
solutionRenderer.setLandmarksVisibility(this.poseTracking.options.landmarkVisibility());
glSurfaceView.setSolutionResultRenderer(solutionRenderer);
glSurfaceView.setRenderInputImage(true); glSurfaceView.setRenderInputImage(true);
setupEventListener(); setupEventListener();
@ -193,7 +198,7 @@ public class Lindera {
} }
private void landmarksToBodyJoints(ImmutableList<LandmarkProto.Landmark> landmarks , BodyJoints bodyJoints){ private void landmarksToBodyJoints(ImmutableList<LandmarkProto.Landmark> 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_INNER), bodyJoints.leftEyeInner);
landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.LEFT_EYE), bodyJoints.leftEye); landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.LEFT_EYE), bodyJoints.leftEye);
@ -242,6 +247,16 @@ public class Lindera {
landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.RIGHT_FOOT), bodyJoints.rightFoot); landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.RIGHT_FOOT), bodyJoints.rightFoot);
landmarkToXYZPointWithConfidence(landmarks.get(PoseTrackingResult.LEFT_FOOT), bodyJoints.leftFoot); 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() { private void startCamera() {

View File

@ -14,16 +14,21 @@
package com.google.mediapipe.solutions.posetracking; package com.google.mediapipe.solutions.posetracking;
import static java.lang.Math.min;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import com.google.auto.value.AutoBuilder; import com.google.auto.value.AutoBuilder;
import com.google.common.collect.ImmutableList; 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.formats.proto.LandmarkProto;
import com.google.mediapipe.framework.Packet; import com.google.mediapipe.framework.Packet;
import com.google.mediapipe.framework.TextureFrame; import com.google.mediapipe.framework.TextureFrame;
import com.google.mediapipe.solutioncore.ImageSolutionResult; 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;
/** /**
@ -35,6 +40,7 @@ public class PoseTrackingResult extends ImageSolutionResult {
private final ImmutableList<Detection> multiPoseDetections; private final ImmutableList<Detection> multiPoseDetections;
private final ImmutableList<LandmarkProto.Landmark> multiPoseLandmarks; private final ImmutableList<LandmarkProto.Landmark> multiPoseLandmarks;
public static final int NOSE = 0; public static final int NOSE = 0;
public static final int LEFT_EYE_INNER = 1; public static final int LEFT_EYE_INNER = 1;
public static final int LEFT_EYE = 2; public static final int LEFT_EYE = 2;
@ -69,9 +75,15 @@ public class PoseTrackingResult extends ImageSolutionResult {
public static final int LEFT_FOOT = 31; public static final int LEFT_FOOT = 31;
public static final int RIGHT_FOOT = 32; public static final int RIGHT_FOOT = 32;
// 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;
PoseTrackingResult( PoseTrackingResult(
ImmutableList<Detection> multiPoseDetections,ImmutableList<LandmarkProto.Landmark> multiPoseLandmarks, Packet imagePacket, long timestamp) { ImmutableList<Detection> multiPoseDetections, ImmutableList<LandmarkProto.Landmark> multiPoseLandmarks, Packet imagePacket, long timestamp) {
this.multiPoseDetections = multiPoseDetections; this.multiPoseDetections = multiPoseDetections;
this.multiPoseLandmarks = multiPoseLandmarks; this.multiPoseLandmarks = multiPoseLandmarks;
this.timestamp = timestamp; this.timestamp = timestamp;
@ -87,19 +99,84 @@ public class PoseTrackingResult extends ImageSolutionResult {
return multiPoseDetections; return multiPoseDetections;
} }
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();
}
LandmarkProto.Landmark getPelvis(ImmutableList<LandmarkProto.Landmark> landmarks) {
// middle point b/w left hip and right hip
return getJointBetweenPoints(landmarks.get(LEFT_HIP), landmarks.get(RIGHT_HIP), 0.5f);
}
LandmarkProto.Landmark getSpinePoint(ImmutableList<LandmarkProto.Landmark> 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);
return getJointBetweenPoints(chest, pelvis, distanceFromShoulders);
}
LandmarkProto.Landmark getHeadTop(ImmutableList<LandmarkProto.Landmark> landmarks) {
float x = 0;
float y = 0;
float z = 0;
final List<Integer> 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();
}
x = x/ptsIdx.size();
y = y/ptsIdx.size();
z = z/ptsIdx.size();
LandmarkProto.Landmark midupper = LandmarkProto.Landmark.newBuilder().setX(x).setY(y).setZ(z).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<LandmarkProto.Landmark> getAdditionalLandmarksByInterpolation(ImmutableList<LandmarkProto.Landmark> originalLandmarks) {
if (originalLandmarks.isEmpty()) return originalLandmarks;
List<LandmarkProto.Landmark> 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<LandmarkProto.Landmark> multiPoseLandmarks() { public ImmutableList<LandmarkProto.Landmark> multiPoseLandmarks() {
return multiPoseLandmarks; return getAdditionalLandmarksByInterpolation(multiPoseLandmarks);
} }
public static Builder builder() { public static Builder builder() {
return new AutoBuilder_PoseTrackingResult_Builder(); return new AutoBuilder_PoseTrackingResult_Builder();
} }
/** Builder for {@link PoseTrackingResult}. */ /**
* Builder for {@link PoseTrackingResult}.
*/
@AutoBuilder @AutoBuilder
public abstract static class Builder { public abstract static class Builder {
abstract Builder setMultiPoseDetections(List<Detection> value); abstract Builder setMultiPoseDetections(List<Detection> value);
abstract Builder setMultiPoseLandmarks(List<LandmarkProto.Landmark> value); abstract Builder setMultiPoseLandmarks(List<LandmarkProto.Landmark> value);
abstract Builder setTimestamp(long value); abstract Builder setTimestamp(long value);

View File

@ -16,7 +16,9 @@ package com.google.mediapipe.solutions.posetracking;
import android.opengl.GLES20; import android.opengl.GLES20;
import com.google.common.collect.ImmutableList;
import com.google.mediapipe.formats.proto.DetectionProto.Detection; import com.google.mediapipe.formats.proto.DetectionProto.Detection;
import com.google.mediapipe.formats.proto.LandmarkProto;
import com.google.mediapipe.solutioncore.ResultGlRenderer; import com.google.mediapipe.solutioncore.ResultGlRenderer;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -52,7 +54,10 @@ public class PoseTrackingResultGlRenderer implements ResultGlRenderer<PoseTracki
private int pointSizeHandle; private int pointSizeHandle;
private int projectionMatrixHandle; private int projectionMatrixHandle;
private int colorHandle; private int colorHandle;
private boolean areLandmarksVisible= true;
public void setLandmarksVisibility(boolean value){
areLandmarksVisible = value;
}
private int loadShader(int type, String shaderCode) { private int loadShader(int type, String shaderCode) {
int shader = GLES20.glCreateShader(type); int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode); GLES20.glShaderSource(shader, shaderCode);
@ -79,17 +84,33 @@ public class PoseTrackingResultGlRenderer implements ResultGlRenderer<PoseTracki
* **/ * **/
@Override @Override
public void renderResult(PoseTrackingResult result, float[] projectionMatrix) { public void renderResult(PoseTrackingResult result, float[] projectionMatrix) {
if (result == null) { if (result == null || !areLandmarksVisible) {
return; return;
} }
GLES20.glUseProgram(program); GLES20.glUseProgram(program);
GLES20.glUniformMatrix4fv(projectionMatrixHandle, 1, false, projectionMatrix, 0); GLES20.glUniformMatrix4fv(projectionMatrixHandle, 1, false, projectionMatrix, 0);
// GLES20.glUniform1f(pointSizeHandle, KEYPOINT_SIZE); GLES20.glUniform1f(pointSizeHandle, KEYPOINT_SIZE);
// int numDetectedFaces = result.multiPoseTrackings().size(); ImmutableList<LandmarkProto.Landmark> landmarks = result.multiPoseLandmarks();
// for (int i = 0; i < numDetectedFaces; ++i) {
// drawDetection(result.multiPoseTrackings().get(i));
// } // 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 +121,8 @@ public class PoseTrackingResultGlRenderer implements ResultGlRenderer<PoseTracki
public void release() { public void release() {
GLES20.glDeleteProgram(program); GLES20.glDeleteProgram(program);
} }
/** /**
* Not needed anymore, to be cleaned * Not needed anymore, to be cleaned
* */ * */