Project import generated by Copybara.

GitOrigin-RevId: f7d09ed033907b893638a8eb4148efa11c0f09a6
This commit is contained in:
MediaPipe Team
2020-11-04 19:09:58 -05:00
committed by chuoling
parent a8d6ce95c4
commit f96eadd6df
250 changed files with 15261 additions and 4620 deletions
@@ -36,9 +36,8 @@ android_binary(
name = "facedetectioncpu",
srcs = glob(["*.java"]),
assets = [
"//mediapipe/graphs/face_detection:mobile_cpu.binarypb",
"//mediapipe/models:face_detection_front.tflite",
"//mediapipe/models:face_detection_front_labelmap.txt",
"//mediapipe/graphs/face_detection:face_detection_mobile_cpu.binarypb",
"//mediapipe/modules/face_detection:face_detection_front.tflite",
],
assets_dir = "",
manifest = "//mediapipe/examples/android/src/java/com/google/mediapipe/apps/basic:AndroidManifest.xml",
@@ -47,7 +46,7 @@ android_binary(
"appName": "Face Detection (CPU)",
"mainActivity": "com.google.mediapipe.apps.basic.MainActivity",
"cameraFacingFront": "True",
"binaryGraphName": "mobile_cpu.binarypb",
"binaryGraphName": "face_detection_mobile_cpu.binarypb",
"inputVideoStreamName": "input_video",
"outputVideoStreamName": "output_video",
"flipFramesVertically": "True",
@@ -36,9 +36,8 @@ android_binary(
name = "facedetectiongpu",
srcs = glob(["*.java"]),
assets = [
"//mediapipe/graphs/face_detection:mobile_gpu.binarypb",
"//mediapipe/models:face_detection_front.tflite",
"//mediapipe/models:face_detection_front_labelmap.txt",
"//mediapipe/graphs/face_detection:face_detection_mobile_gpu.binarypb",
"//mediapipe/modules/face_detection:face_detection_front.tflite",
],
assets_dir = "",
manifest = "//mediapipe/examples/android/src/java/com/google/mediapipe/apps/basic:AndroidManifest.xml",
@@ -47,7 +46,7 @@ android_binary(
"appName": "Face Detection",
"mainActivity": "com.google.mediapipe.apps.basic.MainActivity",
"cameraFacingFront": "True",
"binaryGraphName": "mobile_gpu.binarypb",
"binaryGraphName": "face_detection_mobile_gpu.binarypb",
"inputVideoStreamName": "input_video",
"outputVideoStreamName": "output_video",
"flipFramesVertically": "True",
@@ -37,8 +37,7 @@ android_binary(
srcs = glob(["*.java"]),
assets = [
"//mediapipe/graphs/hand_tracking:hand_detection_mobile_gpu.binarypb",
"//mediapipe/models:palm_detection.tflite",
"//mediapipe/models:palm_detection_labelmap.txt",
"//mediapipe/modules/palm_detection:palm_detection.tflite",
],
assets_dir = "",
manifest = "//mediapipe/examples/android/src/java/com/google/mediapipe/apps/basic:AndroidManifest.xml",
@@ -37,10 +37,9 @@ android_binary(
srcs = glob(["*.java"]),
assets = [
"//mediapipe/graphs/hand_tracking:hand_tracking_mobile_gpu.binarypb",
"//mediapipe/models:handedness.txt",
"//mediapipe/models:hand_landmark.tflite",
"//mediapipe/models:palm_detection.tflite",
"//mediapipe/models:palm_detection_labelmap.txt",
"//mediapipe/modules/hand_landmark:handedness.txt",
"//mediapipe/modules/hand_landmark:hand_landmark.tflite",
"//mediapipe/modules/palm_detection:palm_detection.tflite",
],
assets_dir = "",
manifest = "//mediapipe/examples/android/src/java/com/google/mediapipe/apps/basic:AndroidManifest.xml",
@@ -18,76 +18,75 @@ import android.os.Bundle;
import android.util.Log;
import com.google.mediapipe.formats.proto.LandmarkProto.NormalizedLandmark;
import com.google.mediapipe.formats.proto.LandmarkProto.NormalizedLandmarkList;
import com.google.mediapipe.framework.AndroidPacketCreator;
import com.google.mediapipe.framework.Packet;
import com.google.mediapipe.framework.PacketGetter;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** Main activity of MediaPipe hand tracking app. */
public class MainActivity extends com.google.mediapipe.apps.basic.MainActivity {
private static final String TAG = "MainActivity";
private static final String OUTPUT_HAND_PRESENCE_STREAM_NAME = "hand_presence";
private static final String INPUT_NUM_HANDS_SIDE_PACKET_NAME = "num_hands";
private static final String OUTPUT_LANDMARKS_STREAM_NAME = "hand_landmarks";
// Max number of hands to detect/process.
private static final int NUM_HANDS = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
processor.addPacketCallback(
OUTPUT_HAND_PRESENCE_STREAM_NAME,
(packet) -> {
Boolean handPresence = PacketGetter.getBool(packet);
if (!handPresence) {
Log.d(
TAG,
"[TS:" + packet.getTimestamp() + "] Hand presence is false, no hands detected.");
}
});
AndroidPacketCreator packetCreator = processor.getPacketCreator();
Map<String, Packet> inputSidePackets = new HashMap<>();
inputSidePackets.put(INPUT_NUM_HANDS_SIDE_PACKET_NAME, packetCreator.createInt32(NUM_HANDS));
processor.setInputSidePackets(inputSidePackets);
// To show verbose logging, run:
// adb shell setprop log.tag.MainActivity VERBOSE
if (Log.isLoggable(TAG, Log.VERBOSE)) {
processor.addPacketCallback(
OUTPUT_LANDMARKS_STREAM_NAME,
(packet) -> {
byte[] landmarksRaw = PacketGetter.getProtoBytes(packet);
try {
NormalizedLandmarkList landmarks = NormalizedLandmarkList.parseFrom(landmarksRaw);
if (landmarks == null) {
Log.v(TAG, "[TS:" + packet.getTimestamp() + "] No hand landmarks.");
return;
}
// Note: If hand_presence is false, these landmarks are useless.
OUTPUT_LANDMARKS_STREAM_NAME,
(packet) -> {
Log.v(TAG, "Received multi-hand landmarks packet.");
List<NormalizedLandmarkList> multiHandLandmarks =
PacketGetter.getProtoVector(packet, NormalizedLandmarkList.parser());
Log.v(
TAG,
"[TS:"
+ packet.getTimestamp()
+ "] #Landmarks for hand: "
+ landmarks.getLandmarkCount());
Log.v(TAG, getLandmarksDebugString(landmarks));
} catch (InvalidProtocolBufferException e) {
Log.e(TAG, "Couldn't Exception received - " + e);
return;
}
});
+ "] "
+ getMultiHandLandmarksDebugString(multiHandLandmarks));
});
}
}
private static String getLandmarksDebugString(NormalizedLandmarkList landmarks) {
int landmarkIndex = 0;
String landmarksString = "";
for (NormalizedLandmark landmark : landmarks.getLandmarkList()) {
landmarksString +=
"\t\tLandmark["
+ landmarkIndex
+ "]: ("
+ landmark.getX()
+ ", "
+ landmark.getY()
+ ", "
+ landmark.getZ()
+ ")\n";
++landmarkIndex;
private String getMultiHandLandmarksDebugString(List<NormalizedLandmarkList> multiHandLandmarks) {
if (multiHandLandmarks.isEmpty()) {
return "No hand landmarks";
}
return landmarksString;
String multiHandLandmarksStr = "Number of hands detected: " + multiHandLandmarks.size() + "\n";
int handIndex = 0;
for (NormalizedLandmarkList landmarks : multiHandLandmarks) {
multiHandLandmarksStr +=
"\t#Hand landmarks for hand[" + handIndex + "]: " + landmarks.getLandmarkCount() + "\n";
int landmarkIndex = 0;
for (NormalizedLandmark landmark : landmarks.getLandmarkList()) {
multiHandLandmarksStr +=
"\t\tLandmark ["
+ landmarkIndex
+ "]: ("
+ landmark.getX()
+ ", "
+ landmark.getY()
+ ", "
+ landmark.getZ()
+ ")\n";
++landmarkIndex;
}
++handIndex;
}
return multiHandLandmarksStr;
}
}
@@ -1,64 +0,0 @@
# Copyright 2019 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
package(default_visibility = ["//visibility:private"])
cc_binary(
name = "libmediapipe_jni.so",
linkshared = 1,
linkstatic = 1,
deps = [
"//mediapipe/graphs/hand_tracking:multi_hand_mobile_calculators",
"//mediapipe/java/com/google/mediapipe/framework/jni:mediapipe_framework_jni",
],
)
cc_library(
name = "mediapipe_jni_lib",
srcs = [":libmediapipe_jni.so"],
alwayslink = 1,
)
android_binary(
name = "multihandtrackinggpu",
srcs = glob(["*.java"]),
assets = [
"//mediapipe/graphs/hand_tracking:multi_hand_tracking_mobile_gpu.binarypb",
"//mediapipe/models:handedness.txt",
"//mediapipe/models:hand_landmark.tflite",
"//mediapipe/models:palm_detection.tflite",
"//mediapipe/models:palm_detection_labelmap.txt",
],
assets_dir = "",
manifest = "//mediapipe/examples/android/src/java/com/google/mediapipe/apps/basic:AndroidManifest.xml",
manifest_values = {
"applicationId": "com.google.mediapipe.apps.multihandtrackinggpu",
"appName": "Multi-hand Tracking",
"mainActivity": ".MainActivity",
"cameraFacingFront": "True",
"binaryGraphName": "multi_hand_tracking_mobile_gpu.binarypb",
"inputVideoStreamName": "input_video",
"outputVideoStreamName": "output_video",
"flipFramesVertically": "True",
},
multidex = "native",
deps = [
":mediapipe_jni_lib",
"//mediapipe/examples/android/src/java/com/google/mediapipe/apps/basic:basic_lib",
"//mediapipe/framework/formats:landmark_java_proto_lite",
"//mediapipe/java/com/google/mediapipe/framework:android_framework",
],
)
@@ -1,80 +0,0 @@
// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.mediapipe.apps.multihandtrackinggpu;
import android.os.Bundle;
import android.util.Log;
import com.google.mediapipe.formats.proto.LandmarkProto.NormalizedLandmark;
import com.google.mediapipe.formats.proto.LandmarkProto.NormalizedLandmarkList;
import com.google.mediapipe.framework.PacketGetter;
import java.util.List;
/** Main activity of MediaPipe multi-hand tracking app. */
public class MainActivity extends com.google.mediapipe.apps.basic.MainActivity {
private static final String TAG = "MainActivity";
private static final String OUTPUT_LANDMARKS_STREAM_NAME = "multi_hand_landmarks";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// To show verbose logging, run:
// adb shell setprop log.tag.MainActivity VERBOSE
if (Log.isLoggable(TAG, Log.VERBOSE)) {
processor.addPacketCallback(
OUTPUT_LANDMARKS_STREAM_NAME,
(packet) -> {
Log.v(TAG, "Received multi-hand landmarks packet.");
List<NormalizedLandmarkList> multiHandLandmarks =
PacketGetter.getProtoVector(packet, NormalizedLandmarkList.parser());
Log.v(
TAG,
"[TS:"
+ packet.getTimestamp()
+ "] "
+ getMultiHandLandmarksDebugString(multiHandLandmarks));
});
}
}
private String getMultiHandLandmarksDebugString(List<NormalizedLandmarkList> multiHandLandmarks) {
if (multiHandLandmarks.isEmpty()) {
return "No hand landmarks";
}
String multiHandLandmarksStr = "Number of hands detected: " + multiHandLandmarks.size() + "\n";
int handIndex = 0;
for (NormalizedLandmarkList landmarks : multiHandLandmarks) {
multiHandLandmarksStr +=
"\t#Hand landmarks for hand[" + handIndex + "]: " + landmarks.getLandmarkCount() + "\n";
int landmarkIndex = 0;
for (NormalizedLandmark landmark : landmarks.getLandmarkList()) {
multiHandLandmarksStr +=
"\t\tLandmark ["
+ landmarkIndex
+ "]: ("
+ landmark.getX()
+ ", "
+ landmark.getY()
+ ", "
+ landmark.getZ()
+ ")\n";
++landmarkIndex;
}
++handIndex;
}
return multiHandLandmarksStr;
}
}
@@ -1,4 +1,4 @@
# Copyright 2019 The MediaPipe Authors.
# Copyright 2020 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,16 +12,64 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("@bazel_skylib//lib:selects.bzl", "selects")
load(":build_defs.bzl", "generate_manifest_values")
licenses(["notice"])
package(default_visibility = ["//visibility:private"])
config_setting(
name = "use_chair",
define_values = {
"chair": "true",
},
)
config_setting(
name = "use_cup",
define_values = {
"cup": "true",
},
)
config_setting(
name = "use_camera",
define_values = {
"camera": "true",
},
)
config_setting(
name = "use_shoe_1stage",
define_values = {
"shoe_1stage": "true",
},
)
config_setting(
name = "use_chair_1stage",
define_values = {
"chair_1stage": "true",
},
)
selects.config_setting_group(
name = "1stage",
match_any = [
":use_shoe_1stage",
":use_chair_1stage",
],
)
cc_binary(
name = "libmediapipe_jni.so",
linkshared = 1,
linkstatic = 1,
deps = [
"//mediapipe/graphs/object_detection_3d:mobile_calculators",
deps = select({
"//conditions:default": ["//mediapipe/graphs/object_detection_3d:mobile_calculators"],
":1stage": ["//mediapipe/graphs/object_detection_3d:mobile_calculators_1stage"],
}) + [
"//mediapipe/java/com/google/mediapipe/framework/jni:mediapipe_framework_jni",
],
)
@@ -32,67 +80,108 @@ cc_library(
alwayslink = 1,
)
# To use the "chair" model instead of the default "shoes" model,
# add "--define chair=true" to the bazel build command.
config_setting(
name = "use_chair_model",
define_values = {
"chair": "true",
},
)
genrule(
name = "binary_graph",
srcs = select({
"//conditions:default": ["//mediapipe/graphs/object_detection_3d:mobile_gpu_binary_graph_shoe"],
":use_chair_model": ["//mediapipe/graphs/object_detection_3d:mobile_gpu_binary_graph_chair"],
"//conditions:default": ["//mediapipe/graphs/object_detection_3d:mobile_gpu_binary_graph"],
":1stage": ["//mediapipe/graphs/object_detection_3d:mobile_gpu_1stage_binary_graph"],
}),
outs = ["object_detection_3d.binarypb"],
cmd = "cp $< $@",
)
MODELS_DIR = "//mediapipe/models"
genrule(
name = "model",
srcs = select({
"//conditions:default": ["//mediapipe/models:object_detection_3d_sneakers.tflite"],
":use_chair_model": ["//mediapipe/models:object_detection_3d_chair.tflite"],
"//conditions:default": [MODELS_DIR + ":object_detection_3d_sneakers.tflite"],
":use_chair": [MODELS_DIR + ":object_detection_3d_chair.tflite"],
":use_cup": [MODELS_DIR + ":object_detection_3d_cup.tflite"],
":use_camera": [MODELS_DIR + ":object_detection_3d_camera.tflite"],
":use_shoe_1stage": [MODELS_DIR + ":object_detection_3d_sneakers_1stage.tflite"],
":use_chair_1stage": [MODELS_DIR + ":object_detection_3d_chair_1stage.tflite"],
}),
outs = ["object_detection_3d.tflite"],
cmd = "cp $< $@",
)
MANIFESTS_DIR = "//mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetection3d/manifests"
android_library(
name = "manifest_lib",
exports_manifest = 1,
manifest = select({
"//conditions:default": MANIFESTS_DIR + ":AndroidManifestSneaker.xml",
":use_chair": MANIFESTS_DIR + ":AndroidManifestChair.xml",
":use_cup": MANIFESTS_DIR + ":AndroidManifestCup.xml",
":use_camera": MANIFESTS_DIR + ":AndroidManifestCamera.xml",
":use_shoe_1stage": MANIFESTS_DIR + ":AndroidManifestSneaker.xml",
":use_chair_1stage": MANIFESTS_DIR + ":AndroidManifestChair.xml",
}),
deps = [
"//third_party:opencv",
"@maven//:androidx_concurrent_concurrent_futures",
"@maven//:com_google_guava_guava",
],
)
ASSETS_DIR = "//mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetection3d/assets"
genrule(
name = "mesh",
srcs = select({
"//conditions:default": [ASSETS_DIR + "/sneaker:model.obj.uuu"],
":use_chair": [ASSETS_DIR + "/chair:model.obj.uuu"],
":use_cup": [ASSETS_DIR + "/cup:model.obj.uuu"],
":use_camera": [ASSETS_DIR + "/camera:model.obj.uuu"],
":use_shoe_1stage": [ASSETS_DIR + "/sneaker:model.obj.uuu"],
":use_chair_1stage": [ASSETS_DIR + "/chair:model.obj.uuu"],
}),
outs = ["model.obj.uuu"],
cmd = "cp $< $@",
)
genrule(
name = "texture",
srcs = select({
"//conditions:default": [ASSETS_DIR + "/sneaker:texture.jpg"],
":use_chair": [ASSETS_DIR + "/chair:texture.jpg"],
":use_cup": [ASSETS_DIR + "/cup:texture.jpg"],
":use_camera": [ASSETS_DIR + "/camera:texture.jpg"],
":use_shoe_1stage": [ASSETS_DIR + "/sneaker:texture.jpg"],
":use_chair_1stage": [ASSETS_DIR + "/chair:texture.jpg"],
}),
outs = ["texture.jpg"],
cmd = "cp $< $@",
)
android_binary(
name = "objectdetection3d",
srcs = glob(["*.java"]),
assets = [
":binary_graph",
":model",
"//mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetection3d/assets:box.obj.uuu",
"//mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetection3d/assets:classic_colors.png",
] + select({
"//conditions:default": [
"//mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetection3d/assets/sneaker:model.obj.uuu",
"//mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetection3d/assets/sneaker:texture.jpg",
],
":use_chair_model": [
"//mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetection3d/assets/chair:model.obj.uuu",
"//mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetection3d/assets/chair:texture.jpg",
],
}),
":mesh",
":texture",
MODELS_DIR + ":object_detection_ssd_mobilenetv2_oidv4_fp16.tflite",
MODELS_DIR + ":object_detection_oidv4_labelmap.pbtxt",
ASSETS_DIR + ":box.obj.uuu",
ASSETS_DIR + ":classic_colors.png",
],
assets_dir = "",
manifest = "//mediapipe/examples/android/src/java/com/google/mediapipe/apps/basic:AndroidManifest.xml",
manifest_values = {
"applicationId": "com.google.mediapipe.apps.objectdetection3d",
"appName": "Objectron",
"mainActivity": ".MainActivity",
"cameraFacingFront": "False",
"binaryGraphName": "object_detection_3d.binarypb",
"inputVideoStreamName": "input_video",
"outputVideoStreamName": "output_video",
"flipFramesVertically": "True",
},
manifest_values = select({
"//conditions:default": generate_manifest_values("com.google.mediapipe.apps.objectdetection3d_shoe", "Shoe Objectron"),
":use_chair": generate_manifest_values("com.google.mediapipe.apps.objectdetection3d_chair", "Chair Objectron"),
":use_cup": generate_manifest_values("com.google.mediapipe.apps.objectdetection3d_cup", "Cup Objectron"),
":use_camera": generate_manifest_values("com.google.mediapipe.apps.objectdetection3d_camera", "Camera Objectron"),
":use_shoe_1stage": generate_manifest_values("com.google.mediapipe.apps.objectdetection3d_shoe_1stage", "Single Stage Shoe Objectron"),
":use_chair_1stage": generate_manifest_values("com.google.mediapipe.apps.objectdetection3d_chair_1stage", "Single Stage Chair Objectron"),
}),
multidex = "native",
deps = [
":manifest_lib",
":mediapipe_jni_lib",
"//mediapipe/examples/android/src/java/com/google/mediapipe/apps/basic:basic_lib",
"//mediapipe/framework/formats:landmark_java_proto_lite",
@@ -1,4 +1,4 @@
// Copyright 2019 The MediaPipe Authors.
// Copyright 2020 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,6 +14,9 @@
package com.google.mediapipe.apps.objectdetection3d;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
@@ -40,10 +43,25 @@ public class MainActivity extends com.google.mediapipe.apps.basic.MainActivity {
private Bitmap objTexture = null;
private Bitmap boxTexture = null;
// ApplicationInfo for retrieving metadata defined in the manifest.
private ApplicationInfo applicationInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
applicationInfo =
getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
} catch (NameNotFoundException e) {
Log.e(TAG, "Cannot find application info: " + e);
}
String categoryName = applicationInfo.metaData.getString("categoryName");
float[] modelScale = parseFloatArrayFromString(
applicationInfo.metaData.getString("modelScale"));
float[] modelTransform = parseFloatArrayFromString(
applicationInfo.metaData.getString("modelTransformation"));
prepareDemoAssets();
AndroidPacketCreator packetCreator = processor.getPacketCreator();
Map<String, Packet> inputSidePackets = new HashMap<>();
@@ -51,6 +69,9 @@ public class MainActivity extends com.google.mediapipe.apps.basic.MainActivity {
inputSidePackets.put("box_asset_name", packetCreator.createString(BOX_FILE));
inputSidePackets.put("obj_texture", packetCreator.createRgbaImageFrame(objTexture));
inputSidePackets.put("box_texture", packetCreator.createRgbaImageFrame(boxTexture));
inputSidePackets.put("allowed_labels", packetCreator.createString(categoryName));
inputSidePackets.put("model_scale", packetCreator.createFloat32Array(modelScale));
inputSidePackets.put("model_transformation", packetCreator.createFloat32Array(modelTransform));
processor.setInputSidePackets(inputSidePackets);
}
@@ -134,4 +155,13 @@ public class MainActivity extends com.google.mediapipe.apps.basic.MainActivity {
throw new RuntimeException(e);
}
}
private static float[] parseFloatArrayFromString(String string) {
String[] elements = string.split(",", -1);
float[] array = new float[elements.length];
for (int i = 0; i < elements.length; ++i) {
array[i] = Float.parseFloat(elements[i]);
}
return array;
}
}
@@ -1,4 +1,4 @@
# Copyright 2019 The MediaPipe Authors.
# Copyright 2020 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -11,6 +11,11 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""MediaPipe Python Examples."""
from mediapipe.examples.python.upper_body_pose_tracker import UpperBodyPoseTracker
licenses(["notice"])
package(default_visibility = ["//visibility:public"])
exports_files(
srcs = glob(["**"]),
)
Binary file not shown.

After

Width:  |  Height:  |  Size: 339 KiB

@@ -1,4 +1,4 @@
# Copyright 2019 The MediaPipe Authors.
# Copyright 2020 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -0,0 +1,21 @@
# Copyright 2020 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
package(default_visibility = ["//visibility:public"])
exports_files(
srcs = glob(["**"]),
)
Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

@@ -1,4 +1,4 @@
# Copyright 2019 The MediaPipe Authors.
# Copyright 2020 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -0,0 +1,14 @@
"""Build defs for Objectron."""
def generate_manifest_values(application_id, app_name):
manifest_values = {
"applicationId": application_id,
"appName": app_name,
"mainActivity": "com.google.mediapipe.apps.objectdetection3d.MainActivity",
"cameraFacingFront": "False",
"binaryGraphName": "object_detection_3d.binarypb",
"inputVideoStreamName": "input_video",
"outputVideoStreamName": "output_video",
"flipFramesVertically": "True",
}
return manifest_values
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.mediapipe.apps.objectdetection3d">
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="27" />
<application>
<meta-data android:name="categoryName" android:value="Camera"/>
<meta-data android:name="modelScale" android:value="250, 250, 250"/>
<meta-data android:name="modelTransformation" android:value="1.0, 0.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, -1.0, 0.0, -0.0015,
0.0, 0.0, 0.0, 1.0"/>
</application>
</manifest>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.mediapipe.apps.objectdetection3d">
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="27" />
<application>
<meta-data android:name="categoryName" android:value="Chair"/>
<meta-data android:name="modelScale" android:value="0.1, 0.05, 0.1"/>
<meta-data android:name="modelTransformation" android:value="1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, -10.0,
0.0, 0.0, -1.0, 0.0,
0.0, 0.0, 0.0, 1.0"/>
</application>
</manifest>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.mediapipe.apps.objectdetection3d">
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="27" />
<application>
<meta-data android:name="categoryName" android:value="Coffee cup,Mug"/>
<meta-data android:name="modelScale" android:value="500, 500, 500"/>
<meta-data android:name="modelTransformation" android:value="1.0, 0.0, 0.0, 0.0,
0.0, 0.0, 1.0, -0.001,
0.0, -1.0, 0.0, 0.0,
0.0, 0.0, 0.0, 1.0"/>
</application>
</manifest>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.mediapipe.apps.objectdetection3d">
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="27" />
<application>
<meta-data android:name="categoryName" android:value="Footwear"/>
<meta-data android:name="modelScale" android:value="0.25, 0.25, 0.12"/>
<meta-data android:name="modelTransformation" android:value="1.0, 0.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, -1.0, 0.0, 0.0,
0.0, 0.0, 0.0, 1.0"/>
</application>
</manifest>
@@ -0,0 +1,21 @@
# Copyright 2020 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
package(default_visibility = ["//visibility:public"])
exports_files(
srcs = glob(["**"]),
)
+1 -1
View File
@@ -51,6 +51,6 @@ cc_binary(
name = "face_detection_tpu",
deps = [
"//mediapipe/examples/coral:demo_run_graph_main",
"//mediapipe/graphs/face_detection:desktop_tflite_calculators",
"//mediapipe/graphs/face_detection:desktop_live_calculators",
],
)
@@ -18,14 +18,23 @@ licenses(["notice"])
package(default_visibility = ["//mediapipe/examples:__subpackages__"])
FACE_DETECTION_DEPS = [
"//mediapipe/calculators/image:image_transformation_calculator",
"//mediapipe/calculators/tflite:ssd_anchors_calculator",
"//mediapipe/calculators/tflite:tflite_converter_calculator",
"//mediapipe/calculators/tflite:tflite_inference_calculator",
"//mediapipe/calculators/tflite:tflite_tensors_to_detections_calculator",
"//mediapipe/calculators/util:detection_label_id_to_text_calculator",
"//mediapipe/calculators/util:detection_letterbox_removal_calculator",
"//mediapipe/calculators/util:non_max_suppression_calculator",
]
mediapipe_simple_subgraph(
name = "autoflip_face_detection_subgraph",
graph = "face_detection_subgraph.pbtxt",
register_as = "AutoFlipFaceDetectionSubgraph",
visibility = ["//visibility:public"],
deps = [
"//mediapipe/graphs/face_detection:desktop_tflite_calculators",
],
deps = FACE_DETECTION_DEPS,
)
mediapipe_simple_subgraph(
@@ -33,16 +42,7 @@ mediapipe_simple_subgraph(
graph = "front_face_detection_subgraph.pbtxt",
register_as = "AutoFlipFrontFaceDetectionSubgraph",
visibility = ["//visibility:public"],
deps = [
"//mediapipe/calculators/image:image_transformation_calculator",
"//mediapipe/calculators/tflite:ssd_anchors_calculator",
"//mediapipe/calculators/tflite:tflite_converter_calculator",
"//mediapipe/calculators/tflite:tflite_inference_calculator",
"//mediapipe/calculators/tflite:tflite_tensors_to_detections_calculator",
"//mediapipe/calculators/util:detection_label_id_to_text_calculator",
"//mediapipe/calculators/util:detection_letterbox_removal_calculator",
"//mediapipe/calculators/util:non_max_suppression_calculator",
],
deps = FACE_DETECTION_DEPS,
)
mediapipe_simple_subgraph(
@@ -20,7 +20,7 @@ cc_binary(
name = "face_detection_cpu",
deps = [
"//mediapipe/examples/desktop:demo_run_graph_main",
"//mediapipe/graphs/face_detection:desktop_tflite_calculators",
"//mediapipe/graphs/face_detection:desktop_live_calculators",
],
)
@@ -29,6 +29,6 @@ cc_binary(
name = "face_detection_gpu",
deps = [
"//mediapipe/examples/desktop:demo_run_graph_main_gpu",
"//mediapipe/graphs/face_detection:mobile_calculators",
"//mediapipe/graphs/face_detection:desktop_live_gpu_calculators",
],
)
@@ -1,42 +0,0 @@
# Copyright 2019 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
package(default_visibility = ["//mediapipe/examples:__subpackages__"])
cc_binary(
name = "multi_hand_tracking_tflite",
deps = [
"//mediapipe/examples/desktop:simple_run_graph_main",
"//mediapipe/graphs/hand_tracking:multi_hand_desktop_tflite_calculators",
],
)
cc_binary(
name = "multi_hand_tracking_cpu",
deps = [
"//mediapipe/examples/desktop:demo_run_graph_main",
"//mediapipe/graphs/hand_tracking:multi_hand_desktop_tflite_calculators",
],
)
# Linux only
cc_binary(
name = "multi_hand_tracking_gpu",
deps = [
"//mediapipe/examples/desktop:demo_run_graph_main_gpu",
"//mediapipe/graphs/hand_tracking:multi_hand_mobile_calculators",
],
)
@@ -54,9 +54,8 @@ ios_application(
objc_library(
name = "FaceDetectionCpuAppLibrary",
data = [
"//mediapipe/graphs/face_detection:mobile_cpu_binary_graph",
"//mediapipe/models:face_detection_front.tflite",
"//mediapipe/models:face_detection_front_labelmap.txt",
"//mediapipe/graphs/face_detection:face_detection_mobile_cpu.binarypb",
"//mediapipe/modules/face_detection:face_detection_front.tflite",
],
deps = [
"//mediapipe/examples/ios/common:CommonMediaPipeAppLibrary",
@@ -9,6 +9,6 @@
<key>GraphInputStream</key>
<string>input_video</string>
<key>GraphName</key>
<string>mobile_cpu</string>
<string>face_detection_mobile_cpu</string>
</dict>
</plist>
@@ -54,9 +54,8 @@ ios_application(
objc_library(
name = "FaceDetectionGpuAppLibrary",
data = [
"//mediapipe/graphs/face_detection:mobile_gpu_binary_graph",
"//mediapipe/models:face_detection_front.tflite",
"//mediapipe/models:face_detection_front_labelmap.txt",
"//mediapipe/graphs/face_detection:face_detection_mobile_gpu.binarypb",
"//mediapipe/modules/face_detection:face_detection_front.tflite",
],
deps = [
"//mediapipe/examples/ios/common:CommonMediaPipeAppLibrary",
@@ -9,6 +9,6 @@
<key>GraphInputStream</key>
<string>input_video</string>
<key>GraphName</key>
<string>mobile_gpu</string>
<string>face_detection_mobile_gpu</string>
</dict>
</plist>
+1 -1
View File
@@ -34,7 +34,7 @@ alias(
ios_application(
name = "FaceEffectApp",
app_icons = ["//mediapipe/examples/ios/common:AppIcon"],
bundle_id = BUNDLE_ID_PREFIX + ".FaceMeshGpu",
bundle_id = BUNDLE_ID_PREFIX + ".FaceEffectGpu",
families = [
"iphone",
"ipad",
+1 -1
View File
@@ -60,7 +60,7 @@ objc_library(
"FaceMeshGpuViewController.h",
],
data = [
"//mediapipe/graphs/face_mesh:face_mesh_mobile_gpu_binary_graph",
"//mediapipe/graphs/face_mesh:face_mesh_mobile_gpu.binarypb",
"//mediapipe/modules/face_detection:face_detection_front.tflite",
"//mediapipe/modules/face_landmark:face_landmark.tflite",
],
@@ -55,8 +55,7 @@ objc_library(
name = "HandDetectionGpuAppLibrary",
data = [
"//mediapipe/graphs/hand_tracking:hand_detection_mobile_gpu_binary_graph",
"//mediapipe/models:palm_detection.tflite",
"//mediapipe/models:palm_detection_labelmap.txt",
"//mediapipe/modules/palm_detection:palm_detection.tflite",
],
deps = [
"//mediapipe/examples/ios/common:CommonMediaPipeAppLibrary",
+4 -5
View File
@@ -60,11 +60,10 @@ objc_library(
"HandTrackingViewController.h",
],
data = [
"//mediapipe/graphs/hand_tracking:hand_tracking_mobile_gpu_binary_graph",
"//mediapipe/models:hand_landmark.tflite",
"//mediapipe/models:handedness.txt",
"//mediapipe/models:palm_detection.tflite",
"//mediapipe/models:palm_detection_labelmap.txt",
"//mediapipe/graphs/hand_tracking:hand_tracking_mobile_gpu.binarypb",
"//mediapipe/modules/hand_landmark:hand_landmark.tflite",
"//mediapipe/modules/hand_landmark:handedness.txt",
"//mediapipe/modules/palm_detection:palm_detection.tflite",
],
deps = [
"//mediapipe/examples/ios/common:CommonMediaPipeAppLibrary",
@@ -17,6 +17,10 @@
#include "mediapipe/framework/formats/landmark.pb.h"
static const char* kLandmarksOutputStream = "hand_landmarks";
static const char* kNumHandsInputSidePacket = "num_hands";
// Max number of hands to detect/process.
static const int kNumHands = 2;
@implementation HandTrackingViewController
@@ -25,6 +29,8 @@ static const char* kLandmarksOutputStream = "hand_landmarks";
- (void)viewDidLoad {
[super viewDidLoad];
[self.mediapipeGraph setSidePacket:(mediapipe::MakePacket<int>(kNumHands))
named:kNumHandsInputSidePacket];
[self.mediapipeGraph addFrameOutputStream:kLandmarksOutputStream
outputPacketType:MPPPacketTypeRaw];
}
@@ -40,12 +46,16 @@ static const char* kLandmarksOutputStream = "hand_landmarks";
NSLog(@"[TS:%lld] No hand landmarks", packet.Timestamp().Value());
return;
}
const auto& landmarks = packet.Get<::mediapipe::NormalizedLandmarkList>();
NSLog(@"[TS:%lld] Number of landmarks on hand: %d", packet.Timestamp().Value(),
landmarks.landmark_size());
for (int i = 0; i < landmarks.landmark_size(); ++i) {
NSLog(@"\tLandmark[%d]: (%f, %f, %f)", i, landmarks.landmark(i).x(),
landmarks.landmark(i).y(), landmarks.landmark(i).z());
const auto& multiHandLandmarks = packet.Get<std::vector<::mediapipe::NormalizedLandmarkList>>();
NSLog(@"[TS:%lld] Number of hand instances with landmarks: %lu", packet.Timestamp().Value(),
multiHandLandmarks.size());
for (int handIndex = 0; handIndex < multiHandLandmarks.size(); ++handIndex) {
const auto& landmarks = multiHandLandmarks[handIndex];
NSLog(@"\tNumber of landmarks for hand[%d]: %d", handIndex, landmarks.landmark_size());
for (int i = 0; i < landmarks.landmark_size(); ++i) {
NSLog(@"\t\tLandmark[%d]: (%f, %f, %f)", i, landmarks.landmark(i).x(),
landmarks.landmark(i).y(), landmarks.landmark(i).z());
}
}
}
}
@@ -1,79 +0,0 @@
# Copyright 2019 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load(
"@build_bazel_rules_apple//apple:ios.bzl",
"ios_application",
)
load(
"//mediapipe/examples/ios:bundle_id.bzl",
"BUNDLE_ID_PREFIX",
"example_provisioning",
)
licenses(["notice"])
MIN_IOS_VERSION = "10.0"
alias(
name = "multihandtrackinggpu",
actual = "MultiHandTrackingGpuApp",
)
ios_application(
name = "MultiHandTrackingGpuApp",
app_icons = ["//mediapipe/examples/ios/common:AppIcon"],
bundle_id = BUNDLE_ID_PREFIX + ".MultiHandTrackingGpu",
families = [
"iphone",
"ipad",
],
infoplists = [
"//mediapipe/examples/ios/common:Info.plist",
"Info.plist",
],
minimum_os_version = MIN_IOS_VERSION,
provisioning_profile = example_provisioning(),
deps = [
":MultiHandTrackingGpuAppLibrary",
"@ios_opencv//:OpencvFramework",
],
)
objc_library(
name = "MultiHandTrackingGpuAppLibrary",
srcs = [
"MultiHandTrackingViewController.mm",
],
hdrs = [
"MultiHandTrackingViewController.h",
],
data = [
"//mediapipe/graphs/hand_tracking:multi_hand_tracking_mobile_gpu_binary_graph",
"//mediapipe/models:hand_landmark.tflite",
"//mediapipe/models:handedness.txt",
"//mediapipe/models:palm_detection.tflite",
"//mediapipe/models:palm_detection_labelmap.txt",
],
deps = [
"//mediapipe/examples/ios/common:CommonMediaPipeAppLibrary",
] + select({
"//mediapipe:ios_i386": [],
"//mediapipe:ios_x86_64": [],
"//conditions:default": [
"//mediapipe/graphs/hand_tracking:multi_hand_mobile_calculators",
"//mediapipe/framework/formats:landmark_cc_proto",
],
}),
)
@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CameraPosition</key>
<string>front</string>
<key>MainViewController</key>
<string>MultiHandTrackingViewController</string>
<key>GraphOutputStream</key>
<string>output_video</string>
<key>GraphInputStream</key>
<string>input_video</string>
<key>GraphName</key>
<string>multi_hand_tracking_mobile_gpu</string>
</dict>
</plist>
@@ -1,21 +0,0 @@
// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#import <UIKit/UIKit.h>
#import "mediapipe/examples/ios/common/CommonViewController.h"
@interface MultiHandTrackingViewController : CommonViewController
@end
@@ -1,57 +0,0 @@
// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#import "MultiHandTrackingViewController.h"
#include "mediapipe/framework/formats/landmark.pb.h"
static const char* kLandmarksOutputStream = "multi_hand_landmarks";
@implementation MultiHandTrackingViewController
#pragma mark - UIViewController methods
- (void)viewDidLoad {
[super viewDidLoad];
[self.mediapipeGraph addFrameOutputStream:kLandmarksOutputStream
outputPacketType:MPPPacketTypeRaw];
}
#pragma mark - MPPGraphDelegate methods
// Receives a raw packet from the MediaPipe graph. Invoked on a MediaPipe worker thread.
- (void)mediapipeGraph:(MPPGraph*)graph
didOutputPacket:(const ::mediapipe::Packet&)packet
fromStream:(const std::string&)streamName {
if (streamName == kLandmarksOutputStream) {
if (packet.IsEmpty()) {
NSLog(@"[TS:%lld] No hand landmarks", packet.Timestamp().Value());
return;
}
const auto& multi_hand_landmarks = packet.Get<std::vector<::mediapipe::NormalizedLandmarkList>>();
NSLog(@"[TS:%lld] Number of hand instances with landmarks: %lu", packet.Timestamp().Value(),
multi_hand_landmarks.size());
for (int hand_index = 0; hand_index < multi_hand_landmarks.size(); ++hand_index) {
const auto& landmarks = multi_hand_landmarks[hand_index];
NSLog(@"\tNumber of landmarks for hand[%d]: %d", hand_index, landmarks.landmark_size());
for (int i = 0; i < landmarks.landmark_size(); ++i) {
NSLog(@"\t\tLandmark[%d]: (%f, %f, %f)", i, landmarks.landmark(i).x(),
landmarks.landmark(i).y(), landmarks.landmark(i).z());
}
}
}
}
@end
@@ -1,208 +0,0 @@
# Copyright 2020 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Lint as: python3
"""MediaPipe upper body pose tracker.
MediaPipe upper body pose tracker takes an RGB image as the input and returns
a pose landmark list and an annotated RGB image represented as a numpy ndarray.
Usage examples:
pose_tracker = UpperBodyPoseTracker()
pose_landmarks, _ = pose_tracker.run(
input_file='/tmp/input.png',
output_file='/tmp/output.png')
input_image = cv2.imread('/tmp/input.png')[:, :, ::-1]
pose_landmarks, annotated_image = pose_tracker.run(input_image)
pose_tracker.run_live()
pose_tracker.close()
"""
import os
import time
from typing import Tuple, Union
import cv2
import mediapipe.python as mp
import numpy as np
# resources dependency
from mediapipe.framework.formats import landmark_pb2
# Input and output stream names.
INPUT_VIDEO = 'input_video'
OUTPUT_VIDEO = 'output_video'
POSE_LANDMARKS = 'pose_landmarks'
class UpperBodyPoseTracker:
"""MediaPipe upper body pose tracker."""
def __init__(self):
"""The init method of MediaPipe upper body pose tracker.
The method reads the upper body pose tracking cpu binary graph and
initializes a CalculatorGraph from it. The output packets of pose_landmarks
and output_video output streams will be observed by callbacks. The graph
will be started at the end of this method, waiting for input packets.
"""
# MediaPipe package root path
root_path = os.sep.join( os.path.abspath(__file__).split(os.sep)[:-4])
mp.resource_util.set_resource_dir(root_path)
self._graph = mp.CalculatorGraph(
binary_graph_path=os.path.join(
root_path,
'mediapipe/graphs/pose_tracking/upper_body_pose_tracking_cpu.binarypb'
))
self._outputs = {}
for stream_name in [POSE_LANDMARKS, OUTPUT_VIDEO]:
self._graph.observe_output_stream(stream_name, self._assign_packet)
self._graph.start_run()
def run(
self,
input_frame: np.ndarray = None,
*,
input_file: str = None,
output_file: str = None
) -> Tuple[Union[None, landmark_pb2.NormalizedLandmarkList], np.ndarray]:
"""The run method of MediaPipe upper body pose tracker.
MediaPipe upper body pose tracker takes either the path to an image file or
an RGB image represented as a numpy ndarray and it returns the pose
landmarks list and the annotated RGB image represented as a numpy ndarray.
Args:
input_frame: An RGB image represented as a numpy ndarray.
input_file: The path to an image file.
output_file: The file path that the annotated image will be saved into.
Returns:
pose_landmarks: The pose landmarks list.
annotated_image: The image with pose landmarks annotations.
Raises:
RuntimeError: If the input frame doesn't contain 3 channels (RGB format)
or the input arg is not correctly provided.
Examples
pose_tracker = UpperBodyPoseTracker()
pose_landmarks, _ = pose_tracker.run(
input_file='/tmp/input.png',
output_file='/tmp/output.png')
# Read an image and convert the BGR image to RGB.
input_image = cv2.cvtColor(cv2.imread('/tmp/input.png'), COLOR_BGR2RGB)
pose_landmarks, annotated_image = pose_tracker.run(input_image)
pose_tracker.close()
"""
if input_file is None and input_frame is None:
raise RuntimeError(
'Must provide either a path to an image file or an RGB image represented as a numpy.ndarray.'
)
if input_file:
if input_frame is not None:
raise RuntimeError(
'Must only provide either \'input_file\' or \'input_frame\'.')
else:
input_frame = cv2.imread(input_file)[:, :, ::-1]
pose_landmarks, annotated_image = self._run_graph(input_frame)
if output_file:
cv2.imwrite(output_file, annotated_image[:, :, ::-1])
return pose_landmarks, annotated_image
def run_live(self) -> None:
"""Run MediaPipe upper body pose tracker with live camera input.
The method will be self-terminated after 30 seconds. If you need to
terminate it earlier, press the Esc key to stop the run manually. Note that
you need to select the output image window rather than the terminal window
first and then press the key.
Examples:
pose_tracker = UpperBodyPoseTracker()
pose_tracker.run_live()
pose_tracker.close()
"""
cap = cv2.VideoCapture(0)
start_time = time.time()
print(
'Press Esc within the output image window to stop the run, or let it '
'self terminate after 30 seconds.')
while cap.isOpened() and time.time() - start_time < 30:
success, input_frame = cap.read()
if not success:
break
input_frame = cv2.cvtColor(cv2.flip(input_frame, 1), cv2.COLOR_BGR2RGB)
input_frame.flags.writeable = False
_, output_frame = self._run_graph(input_frame)
cv2.imshow('MediaPipe upper body pose tracker',
cv2.cvtColor(output_frame, cv2.COLOR_RGB2BGR))
if cv2.waitKey(5) & 0xFF == 27:
break
cap.release()
cv2.destroyAllWindows()
def close(self) -> None:
self._graph.close()
self._graph = None
self._outputs = None
def _run_graph(
self,
input_frame: np.ndarray = None,
) -> Tuple[Union[None, landmark_pb2.NormalizedLandmarkList], np.ndarray]:
"""The internal run graph method.
Args:
input_frame: An RGB image represented as a numpy ndarray.
Returns:
pose_landmarks: The pose landmarks list.
annotated_image: The image with pose landmarks annotations.
Raises:
RuntimeError: If the input frame doesn't contain 3 channels representing
RGB.
"""
if input_frame.shape[2] != 3:
raise RuntimeError('input frame must have 3 channels.')
self._outputs.clear()
start_time = time.time()
self._graph.add_packet_to_input_stream(
stream=INPUT_VIDEO,
packet=mp.packet_creator.create_image_frame(
image_format=mp.ImageFormat.SRGB, data=input_frame),
timestamp=mp.Timestamp.from_seconds(start_time))
self._graph.wait_until_idle()
pose_landmarks = None
if POSE_LANDMARKS in self._outputs:
pose_landmarks = mp.packet_getter.get_proto(self._outputs[POSE_LANDMARKS])
annotated_image = mp.packet_getter.get_image_frame(
self._outputs[OUTPUT_VIDEO]).numpy_view()
print('UpperBodyPoseTracker.Run() took',
time.time() - start_time, 'seconds')
return pose_landmarks, annotated_image
def _assign_packet(self, stream_name: str, packet: mp.Packet) -> None:
self._outputs[stream_name] = packet