Add mediapipe tasks face blendshapes graph
PiperOrigin-RevId: 509995915
This commit is contained in:
parent
bdd1c24990
commit
ba10ae8410
|
@ -18,6 +18,32 @@ package(default_visibility = [
|
||||||
|
|
||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "face_blendshapes_graph",
|
||||||
|
srcs = ["face_blendshapes_graph.cc"],
|
||||||
|
deps = [
|
||||||
|
"//mediapipe/calculators/core:split_proto_list_calculator",
|
||||||
|
"//mediapipe/calculators/core:split_vector_calculator",
|
||||||
|
"//mediapipe/calculators/core:split_vector_calculator_cc_proto",
|
||||||
|
"//mediapipe/calculators/tensor:inference_calculator",
|
||||||
|
"//mediapipe/calculators/tensor:landmarks_to_tensor_calculator",
|
||||||
|
"//mediapipe/calculators/tensor:landmarks_to_tensor_calculator_cc_proto",
|
||||||
|
"//mediapipe/calculators/tensor:tensors_to_classification_calculator",
|
||||||
|
"//mediapipe/calculators/tensor:tensors_to_classification_calculator_cc_proto",
|
||||||
|
"//mediapipe/framework/api2:builder",
|
||||||
|
"//mediapipe/framework/api2:port",
|
||||||
|
"//mediapipe/framework/formats:classification_cc_proto",
|
||||||
|
"//mediapipe/framework/formats:landmark_cc_proto",
|
||||||
|
"//mediapipe/framework/formats:tensor",
|
||||||
|
"//mediapipe/framework/port:status",
|
||||||
|
"//mediapipe/tasks/cc/core:model_asset_bundle_resources",
|
||||||
|
"//mediapipe/tasks/cc/core:model_resources_cache",
|
||||||
|
"//mediapipe/tasks/cc/core:model_task_graph",
|
||||||
|
"//mediapipe/tasks/cc/vision/face_landmarker/proto:face_blendshapes_graph_options_cc_proto",
|
||||||
|
],
|
||||||
|
alwayslink = 1,
|
||||||
|
)
|
||||||
|
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "face_landmarks_detector_graph",
|
name = "face_landmarks_detector_graph",
|
||||||
srcs = ["face_landmarks_detector_graph.cc"],
|
srcs = ["face_landmarks_detector_graph.cc"],
|
||||||
|
|
|
@ -0,0 +1,326 @@
|
||||||
|
/* Copyright 2023 The MediaPipe Authors. All Rights Reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
==============================================================================*/
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "mediapipe/calculators/core/split_vector_calculator.pb.h"
|
||||||
|
#include "mediapipe/calculators/tensor/landmarks_to_tensor_calculator.h"
|
||||||
|
#include "mediapipe/calculators/tensor/landmarks_to_tensor_calculator.pb.h"
|
||||||
|
#include "mediapipe/calculators/tensor/tensors_to_classification_calculator.pb.h"
|
||||||
|
#include "mediapipe/framework/api2/builder.h"
|
||||||
|
#include "mediapipe/framework/api2/port.h"
|
||||||
|
#include "mediapipe/framework/formats/classification.pb.h"
|
||||||
|
#include "mediapipe/framework/formats/landmark.pb.h"
|
||||||
|
#include "mediapipe/framework/formats/tensor.h"
|
||||||
|
#include "mediapipe/framework/port/status_macros.h"
|
||||||
|
#include "mediapipe/tasks/cc/core/model_task_graph.h"
|
||||||
|
#include "mediapipe/tasks/cc/vision/face_landmarker/proto/face_blendshapes_graph_options.pb.h"
|
||||||
|
|
||||||
|
namespace mediapipe {
|
||||||
|
namespace tasks {
|
||||||
|
namespace vision {
|
||||||
|
namespace face_landmarker {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using ::mediapipe::api2::Input;
|
||||||
|
using ::mediapipe::api2::LandmarksToTensorCalculator;
|
||||||
|
using ::mediapipe::api2::Output;
|
||||||
|
using ::mediapipe::api2::builder::Graph;
|
||||||
|
using ::mediapipe::api2::builder::Stream;
|
||||||
|
using ::mediapipe::tasks::vision::face_landmarker::proto::
|
||||||
|
FaceBlendshapesGraphOptions;
|
||||||
|
|
||||||
|
constexpr char kLandmarksTag[] = "LANDMARKS";
|
||||||
|
constexpr char kImageSizeTag[] = "IMAGE_SIZE";
|
||||||
|
constexpr char kBlendshapesTag[] = "BLENDSHAPES";
|
||||||
|
|
||||||
|
// Subset of 478 landmarks required for the HUND model.
|
||||||
|
static constexpr std::array<int, 146> kLandmarksSubsetIdxs = {
|
||||||
|
0, 1, 4, 5, 6, 7, 8, 10, 13, 14, 17, 21, 33, 37, 39,
|
||||||
|
40, 46, 52, 53, 54, 55, 58, 61, 63, 65, 66, 67, 70, 78, 80,
|
||||||
|
81, 82, 84, 87, 88, 91, 93, 95, 103, 105, 107, 109, 127, 132, 133,
|
||||||
|
136, 144, 145, 146, 148, 149, 150, 152, 153, 154, 155, 157, 158, 159, 160,
|
||||||
|
161, 162, 163, 168, 172, 173, 176, 178, 181, 185, 191, 195, 197, 234, 246,
|
||||||
|
249, 251, 263, 267, 269, 270, 276, 282, 283, 284, 285, 288, 291, 293, 295,
|
||||||
|
296, 297, 300, 308, 310, 311, 312, 314, 317, 318, 321, 323, 324, 332, 334,
|
||||||
|
336, 338, 356, 361, 362, 365, 373, 374, 375, 377, 378, 379, 380, 381, 382,
|
||||||
|
384, 385, 386, 387, 388, 389, 390, 397, 398, 400, 402, 405, 409, 415, 454,
|
||||||
|
466, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477};
|
||||||
|
static constexpr std::array<absl::string_view, 52> kBlendshapeNames = {
|
||||||
|
"_neutral",
|
||||||
|
"browDownLeft",
|
||||||
|
"browDownRight",
|
||||||
|
"browInnerUp",
|
||||||
|
"browOuterUpLeft",
|
||||||
|
"browOuterUpRight",
|
||||||
|
"cheekPuff",
|
||||||
|
"cheekSquintLeft",
|
||||||
|
"cheekSquintRight",
|
||||||
|
"eyeBlinkLeft",
|
||||||
|
"eyeBlinkRight",
|
||||||
|
"eyeLookDownLeft",
|
||||||
|
"eyeLookDownRight",
|
||||||
|
"eyeLookInLeft",
|
||||||
|
"eyeLookInRight",
|
||||||
|
"eyeLookOutLeft",
|
||||||
|
"eyeLookOutRight",
|
||||||
|
"eyeLookUpLeft",
|
||||||
|
"eyeLookUpRight",
|
||||||
|
"eyeSquintLeft",
|
||||||
|
"eyeSquintRight",
|
||||||
|
"eyeWideLeft",
|
||||||
|
"eyeWideRight",
|
||||||
|
"jawForward",
|
||||||
|
"jawLeft",
|
||||||
|
"jawOpen",
|
||||||
|
"jawRight",
|
||||||
|
"mouthClose",
|
||||||
|
"mouthDimpleLeft",
|
||||||
|
"mouthDimpleRight",
|
||||||
|
"mouthFrownLeft",
|
||||||
|
"mouthFrownRight",
|
||||||
|
"mouthFunnel",
|
||||||
|
"mouthLeft",
|
||||||
|
"mouthLowerDownLeft",
|
||||||
|
"mouthLowerDownRight",
|
||||||
|
"mouthPressLeft",
|
||||||
|
"mouthPressRight",
|
||||||
|
"mouthPucker",
|
||||||
|
"mouthRight",
|
||||||
|
"mouthRollLower",
|
||||||
|
"mouthRollUpper",
|
||||||
|
"mouthShrugLower",
|
||||||
|
"mouthShrugUpper",
|
||||||
|
"mouthSmileLeft",
|
||||||
|
"mouthSmileRight",
|
||||||
|
"mouthStretchLeft",
|
||||||
|
"mouthStretchRight",
|
||||||
|
"mouthUpperUpLeft",
|
||||||
|
"mouthUpperUpRight",
|
||||||
|
"noseSneerLeft",
|
||||||
|
"noseSneerRight"};
|
||||||
|
|
||||||
|
struct FaceBlendshapesOuts {
|
||||||
|
Stream<ClassificationList> blendshapes;
|
||||||
|
};
|
||||||
|
|
||||||
|
Stream<NormalizedLandmarkList> GetLandmarksSubset(
|
||||||
|
Stream<NormalizedLandmarkList> landmarks,
|
||||||
|
const std::array<int, 146>& subset_idxs, Graph& graph) {
|
||||||
|
auto& node = graph.AddNode("SplitNormalizedLandmarkListCalculator");
|
||||||
|
auto& opts = node.GetOptions<SplitVectorCalculatorOptions>();
|
||||||
|
for (int i = 0; i < subset_idxs.size(); ++i) {
|
||||||
|
auto* range = opts.add_ranges();
|
||||||
|
range->set_begin(subset_idxs[i]);
|
||||||
|
range->set_end(subset_idxs[i] + 1);
|
||||||
|
}
|
||||||
|
opts.set_combine_outputs(true);
|
||||||
|
landmarks >> node.In("");
|
||||||
|
return node.Out("").Cast<NormalizedLandmarkList>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<std::vector<Tensor>> ConvertLandmarksToTensor(
|
||||||
|
Stream<NormalizedLandmarkList> landmarks,
|
||||||
|
Stream<std::pair<int, int>> img_size, Graph& graph) {
|
||||||
|
auto& node = graph.AddNode<LandmarksToTensorCalculator>();
|
||||||
|
auto& opts = node.GetOptions<LandmarksToTensorCalculatorOptions>();
|
||||||
|
opts.add_attributes(LandmarksToTensorCalculatorOptions::X);
|
||||||
|
opts.add_attributes(LandmarksToTensorCalculatorOptions::Y);
|
||||||
|
opts.set_flatten(false);
|
||||||
|
landmarks >> node[LandmarksToTensorCalculator::kInNormLandmarkList];
|
||||||
|
img_size >> node[LandmarksToTensorCalculator::kImageSize];
|
||||||
|
return node[LandmarksToTensorCalculator::kOutTensors];
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<std::vector<Tensor>> GetTensorWithBlendshapes(
|
||||||
|
Stream<std::vector<Tensor>> tensors, Graph& graph) {
|
||||||
|
auto& node = graph.AddNode("SplitTensorVectorCalculator");
|
||||||
|
auto& opts = node.GetOptions<SplitVectorCalculatorOptions>();
|
||||||
|
auto* range = opts.add_ranges();
|
||||||
|
range->set_begin(0);
|
||||||
|
range->set_end(1);
|
||||||
|
opts.set_combine_outputs(true);
|
||||||
|
tensors >> node.In(0);
|
||||||
|
return node.Out(0).Cast<std::vector<Tensor>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<ClassificationList> ConvertTensorToBlendshapes(
|
||||||
|
Stream<std::vector<Tensor>> tensors,
|
||||||
|
const std::array<absl::string_view, 52>& labels, Graph& graph) {
|
||||||
|
auto& node = graph.AddNode("TensorsToClassificationCalculator");
|
||||||
|
auto& opts = node.GetOptions<TensorsToClassificationCalculatorOptions>();
|
||||||
|
// Disable top_k and min_score_threshold logic to return coefficients as is.
|
||||||
|
opts.set_top_k(0);
|
||||||
|
opts.set_min_score_threshold(-1.0);
|
||||||
|
for (int i = 0; i < labels.size(); ++i) {
|
||||||
|
auto* entry = opts.mutable_label_map()->add_entries();
|
||||||
|
entry->set_id(i);
|
||||||
|
// TODO: Replace with entry->set_label(labels[i])
|
||||||
|
entry->mutable_label()->assign(labels[i].data(), labels[i].size());
|
||||||
|
}
|
||||||
|
tensors >> node.In("TENSORS");
|
||||||
|
return node.Out("CLASSIFICATIONS").Cast<ClassificationList>();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Predicts face blendshapes from landmarks.
|
||||||
|
//
|
||||||
|
// Inputs:
|
||||||
|
// LANDMARKS - NormalizedLandmarkList
|
||||||
|
// 478 2.5D face landmarks predicted by an Attention Mesh model.
|
||||||
|
// IMAGE_SIZE - std::pair<int, int>
|
||||||
|
// Input frame size.
|
||||||
|
//
|
||||||
|
// Outputs:
|
||||||
|
// FACE_BLENDSHAPES - ClassificationList
|
||||||
|
// if EXTRA_FACE_BLENDSHAPES is provided, we have 53 blendshape coeffs
|
||||||
|
// output; if not, 52 coeffs output.
|
||||||
|
// All 52 blendshape coefficients:
|
||||||
|
// 0 - _neutral (ignore it)
|
||||||
|
// 1 - browDownLeft
|
||||||
|
// 2 - browDownRight
|
||||||
|
// 3 - browInnerUp
|
||||||
|
// 4 - browOuterUpLeft
|
||||||
|
// 5 - browOuterUpRight
|
||||||
|
// 6 - cheekPuff
|
||||||
|
// 7 - cheekSquintLeft
|
||||||
|
// 8 - cheekSquintRight
|
||||||
|
// 9 - eyeBlinkLeft
|
||||||
|
// 10 - eyeBlinkRight
|
||||||
|
// 11 - eyeLookDownLeft
|
||||||
|
// 12 - eyeLookDownRight
|
||||||
|
// 13 - eyeLookInLeft
|
||||||
|
// 14 - eyeLookInRight
|
||||||
|
// 15 - eyeLookOutLeft
|
||||||
|
// 16 - eyeLookOutRight
|
||||||
|
// 17 - eyeLookUpLeft
|
||||||
|
// 18 - eyeLookUpRight
|
||||||
|
// 19 - eyeSquintLeft
|
||||||
|
// 20 - eyeSquintRight
|
||||||
|
// 21 - eyeWideLeft
|
||||||
|
// 22 - eyeWideRight
|
||||||
|
// 23 - jawForward
|
||||||
|
// 24 - jawLeft
|
||||||
|
// 25 - jawOpen
|
||||||
|
// 26 - jawRight
|
||||||
|
// 27 - mouthClose
|
||||||
|
// 28 - mouthDimpleLeft
|
||||||
|
// 29 - mouthDimpleRight
|
||||||
|
// 30 - mouthFrownLeft
|
||||||
|
// 31 - mouthFrownRight
|
||||||
|
// 32 - mouthFunnel
|
||||||
|
// 33 - mouthLeft
|
||||||
|
// 34 - mouthLowerDownLeft
|
||||||
|
// 35 - mouthLowerDownRight
|
||||||
|
// 36 - mouthPressLeft
|
||||||
|
// 37 - mouthPressRight
|
||||||
|
// 38 - mouthPucker
|
||||||
|
// 39 - mouthRight
|
||||||
|
// 40 - mouthRollLower
|
||||||
|
// 41 - mouthRollUpper
|
||||||
|
// 42 - mouthShrugLower
|
||||||
|
// 43 - mouthShrugUpper
|
||||||
|
// 44 - mouthSmileLeft
|
||||||
|
// 45 - mouthSmileRight
|
||||||
|
// 46 - mouthStretchLeft
|
||||||
|
// 47 - mouthStretchRight
|
||||||
|
// 48 - mouthUpperUpLeft
|
||||||
|
// 49 - mouthUpperUpRight
|
||||||
|
// 50 - noseSneerLeft
|
||||||
|
// 51 - noseSneerRight
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// node {
|
||||||
|
// calculator: "mediapipe.tasks.vision.face_landmarker.FaceBlendshapesGraph"
|
||||||
|
// input_stream: "LANDMARKS:face_landmarks"
|
||||||
|
// input_stream: "IMAGE_SIZE:image_size"
|
||||||
|
// output_stream: "BLENDSHAPES:face_blendshapes"
|
||||||
|
// options {
|
||||||
|
// [mediapipe.tasks.vision.face_landmarker.proto.FaceBlendshapesGraphOptions.ext]
|
||||||
|
// {
|
||||||
|
// base_options {
|
||||||
|
// model_asset {
|
||||||
|
// file_name: "face_blendshapes.tflite"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
class FaceBlendshapesGraph : public core::ModelTaskGraph {
|
||||||
|
public:
|
||||||
|
absl::StatusOr<CalculatorGraphConfig> GetConfig(SubgraphContext* sc) {
|
||||||
|
ASSIGN_OR_RETURN(const auto* model_resources,
|
||||||
|
CreateModelResources<FaceBlendshapesGraphOptions>(sc));
|
||||||
|
Graph graph;
|
||||||
|
ASSIGN_OR_RETURN(
|
||||||
|
auto face_blendshapes_outs,
|
||||||
|
BuildFaceBlendshapesSubgraph(
|
||||||
|
sc->Options<FaceBlendshapesGraphOptions>(), *model_resources,
|
||||||
|
graph[Input<NormalizedLandmarkList>(kLandmarksTag)],
|
||||||
|
graph[Input<std::pair<int, int>>(kImageSizeTag)], graph));
|
||||||
|
face_blendshapes_outs.blendshapes >>
|
||||||
|
graph[Output<ClassificationList>(kBlendshapesTag)];
|
||||||
|
|
||||||
|
return graph.GetConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Updates graph to predict face blendshapes from landmarks. Returns list of
|
||||||
|
// blendsahpes.
|
||||||
|
//
|
||||||
|
// subgraph_options: the mediapipe tasks module FaceBlendshapesGraphOptions.
|
||||||
|
// model_resources: the ModelSources object initialized from a face
|
||||||
|
// blendshapes model file with model metadata.
|
||||||
|
// landmarks: 478 normalized face landmarks
|
||||||
|
// img_size: Image size to denormalize landmarks.
|
||||||
|
// graph: the mediapipe builder::Graph instance to be updated.
|
||||||
|
absl::StatusOr<FaceBlendshapesOuts> BuildFaceBlendshapesSubgraph(
|
||||||
|
const FaceBlendshapesGraphOptions& subgraph_options,
|
||||||
|
const core::ModelResources& model_resources,
|
||||||
|
Stream<NormalizedLandmarkList> landmarks,
|
||||||
|
Stream<std::pair<int, int>> img_size, Graph& graph) {
|
||||||
|
// Take required subset of landmarks.
|
||||||
|
landmarks = GetLandmarksSubset(landmarks, kLandmarksSubsetIdxs, graph);
|
||||||
|
|
||||||
|
// Convert landmarks to input tensor.
|
||||||
|
auto tensor_in = ConvertLandmarksToTensor(landmarks, img_size, graph);
|
||||||
|
|
||||||
|
// Run Blendshapes model.
|
||||||
|
auto& inference = AddInference(
|
||||||
|
model_resources, subgraph_options.base_options().acceleration(), graph);
|
||||||
|
tensor_in >> inference.In("TENSORS");
|
||||||
|
auto tensors_out = inference.Out("TENSORS").Cast<std::vector<Tensor>>();
|
||||||
|
|
||||||
|
// Take output tensor with blendshapes and wrap it in vector.
|
||||||
|
auto blendshapes_tensor = GetTensorWithBlendshapes(tensors_out, graph);
|
||||||
|
|
||||||
|
// Convert tensor to ClassificationList.
|
||||||
|
auto face_blendshapes =
|
||||||
|
ConvertTensorToBlendshapes(blendshapes_tensor, kBlendshapeNames, graph);
|
||||||
|
|
||||||
|
return FaceBlendshapesOuts{face_blendshapes};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
REGISTER_MEDIAPIPE_GRAPH(
|
||||||
|
::mediapipe::tasks::vision::face_landmarker::FaceBlendshapesGraph);
|
||||||
|
|
||||||
|
} // namespace face_landmarker
|
||||||
|
} // namespace vision
|
||||||
|
} // namespace tasks
|
||||||
|
} // namespace mediapipe
|
|
@ -0,0 +1,173 @@
|
||||||
|
/* Copyright 2023 The MediaPipe Authors. All Rights Reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
==============================================================================*/
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "mediapipe/framework/api2/builder.h"
|
||||||
|
#include "mediapipe/framework/api2/port.h"
|
||||||
|
#include "mediapipe/framework/deps/file_path.h"
|
||||||
|
#include "mediapipe/framework/formats/classification.pb.h"
|
||||||
|
#include "mediapipe/framework/formats/landmark.pb.h"
|
||||||
|
#include "mediapipe/framework/port/file_helpers.h"
|
||||||
|
#include "mediapipe/framework/port/gmock.h"
|
||||||
|
#include "mediapipe/framework/port/gtest.h"
|
||||||
|
#include "mediapipe/framework/port/parse_text_proto.h"
|
||||||
|
#include "mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.h"
|
||||||
|
#include "mediapipe/tasks/cc/core/proto/base_options.pb.h"
|
||||||
|
#include "mediapipe/tasks/cc/core/task_runner.h"
|
||||||
|
#include "mediapipe/tasks/cc/vision/face_landmarker/proto/face_blendshapes_graph_options.pb.h"
|
||||||
|
#include "tensorflow/lite/core/shims/cc/shims_test_util.h"
|
||||||
|
|
||||||
|
namespace mediapipe {
|
||||||
|
namespace tasks {
|
||||||
|
namespace vision {
|
||||||
|
namespace face_landmarker {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using ::file::Defaults;
|
||||||
|
using ::mediapipe::api2::Input;
|
||||||
|
using ::mediapipe::api2::Output;
|
||||||
|
using ::mediapipe::api2::builder::Graph;
|
||||||
|
using ::mediapipe::file::JoinPath;
|
||||||
|
using ::mediapipe::tasks::core::TaskRunner;
|
||||||
|
using ::mediapipe::tasks::vision::face_landmarker::proto::
|
||||||
|
FaceBlendshapesGraphOptions;
|
||||||
|
|
||||||
|
constexpr char kTestDataDirectory[] = "/mediapipe/tasks/testdata/vision/";
|
||||||
|
constexpr char kFaceBlendshapesModel[] = "face_blendshapes.tflite";
|
||||||
|
constexpr char kInLandmarks[] = "face_blendshapes_in_landmarks.prototxt";
|
||||||
|
constexpr char kOutBlendshapes[] = "face_blendshapes_out.prototxt";
|
||||||
|
constexpr float kSimilarityThreshold = 0.1;
|
||||||
|
constexpr std::string_view kGeneratedGraph =
|
||||||
|
"face_blendshapes_generated_graph.pbtxt";
|
||||||
|
|
||||||
|
constexpr char kLandmarksTag[] = "LANDMARKS";
|
||||||
|
constexpr char kLandmarksName[] = "landmarks";
|
||||||
|
constexpr char kImageSizeTag[] = "IMAGE_SIZE";
|
||||||
|
constexpr char kImageSizeName[] = "image_size";
|
||||||
|
constexpr char kBlendshapesTag[] = "BLENDSHAPES";
|
||||||
|
constexpr char kBlendshapesName[] = "blendshapes";
|
||||||
|
|
||||||
|
absl::StatusOr<CalculatorGraphConfig> ExpandConfig(
|
||||||
|
const std::string& config_str) {
|
||||||
|
auto config =
|
||||||
|
mediapipe::ParseTextProtoOrDie<CalculatorGraphConfig>(config_str);
|
||||||
|
CalculatorGraph graph;
|
||||||
|
MP_RETURN_IF_ERROR(graph.Initialize(config));
|
||||||
|
return graph.Config();
|
||||||
|
}
|
||||||
|
|
||||||
|
NormalizedLandmarkList GetLandmarks(absl::string_view filename) {
|
||||||
|
NormalizedLandmarkList landmarks;
|
||||||
|
MP_EXPECT_OK(GetTextProto(file::JoinPath("./", kTestDataDirectory, filename),
|
||||||
|
&landmarks, Defaults()));
|
||||||
|
return landmarks;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassificationList GetBlendshapes(absl::string_view filename) {
|
||||||
|
ClassificationList blendshapes;
|
||||||
|
MP_EXPECT_OK(GetTextProto(file::JoinPath("./", kTestDataDirectory, filename),
|
||||||
|
&blendshapes, Defaults()));
|
||||||
|
return blendshapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to create a Face Blendshapes TaskRunner.
|
||||||
|
absl::StatusOr<std::unique_ptr<TaskRunner>> CreateTaskRunner() {
|
||||||
|
Graph graph;
|
||||||
|
auto& face_blendshapes_graph = graph.AddNode(
|
||||||
|
"mediapipe.tasks.vision.face_landmarker.FaceBlendshapesGraph");
|
||||||
|
auto& options =
|
||||||
|
face_blendshapes_graph.GetOptions<FaceBlendshapesGraphOptions>();
|
||||||
|
options.mutable_base_options()->mutable_model_asset()->set_file_name(
|
||||||
|
JoinPath("./", kTestDataDirectory, kFaceBlendshapesModel));
|
||||||
|
|
||||||
|
graph[Input<NormalizedLandmarkList>(kLandmarksTag)].SetName(kLandmarksName) >>
|
||||||
|
face_blendshapes_graph.In(kLandmarksTag);
|
||||||
|
graph[Input<std::pair<int, int>>(kImageSizeTag)].SetName(kImageSizeName) >>
|
||||||
|
face_blendshapes_graph.In(kImageSizeTag);
|
||||||
|
face_blendshapes_graph.Out(kBlendshapesTag).SetName(kBlendshapesName) >>
|
||||||
|
graph[Output<ClassificationList>(kBlendshapesTag)];
|
||||||
|
|
||||||
|
return TaskRunner::Create(
|
||||||
|
graph.GetConfig(), absl::make_unique<core::MediaPipeBuiltinOpResolver>());
|
||||||
|
}
|
||||||
|
|
||||||
|
class FaceBlendshapesTest : public tflite_shims::testing::Test {};
|
||||||
|
|
||||||
|
TEST_F(FaceBlendshapesTest, SmokeTest) {
|
||||||
|
// Prepare graph inputs.
|
||||||
|
auto in_landmarks = GetLandmarks(kInLandmarks);
|
||||||
|
std::pair<int, int> in_image_size = {820, 1024};
|
||||||
|
|
||||||
|
// Run graph.
|
||||||
|
MP_ASSERT_OK_AND_ASSIGN(auto task_runner, CreateTaskRunner());
|
||||||
|
auto output_packets = task_runner->Process(
|
||||||
|
{{kLandmarksName,
|
||||||
|
MakePacket<NormalizedLandmarkList>(std::move(in_landmarks))},
|
||||||
|
{kImageSizeName,
|
||||||
|
MakePacket<std::pair<int, int>>(std::move(in_image_size))}});
|
||||||
|
MP_ASSERT_OK(output_packets);
|
||||||
|
|
||||||
|
// Compare with expected result.
|
||||||
|
const auto& actual_blendshapes =
|
||||||
|
(*output_packets)[kBlendshapesName].Get<ClassificationList>();
|
||||||
|
auto expected_blendshapes = GetBlendshapes(kOutBlendshapes);
|
||||||
|
EXPECT_THAT(
|
||||||
|
actual_blendshapes,
|
||||||
|
testing::proto::Approximately(testing::EqualsProto(expected_blendshapes),
|
||||||
|
kSimilarityThreshold));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FaceRigGhumGpuTest, VerifyGraph) {
|
||||||
|
MP_ASSERT_OK_AND_ASSIGN(
|
||||||
|
auto actual_graph,
|
||||||
|
ExpandConfig(
|
||||||
|
R"pb(
|
||||||
|
node {
|
||||||
|
calculator: "mediapipe.tasks.vision.face_landmarker.FaceBlendshapesGraph"
|
||||||
|
input_stream: "LANDMARKS:landmarks"
|
||||||
|
input_stream: "IMAGE_SIZE:image_size"
|
||||||
|
output_stream: "BLENDSHAPES:blendshapes"
|
||||||
|
options {
|
||||||
|
[mediapipe.tasks.vision.face_landmarker.proto
|
||||||
|
.FaceBlendshapesGraphOptions.ext] {
|
||||||
|
base_options {
|
||||||
|
model_asset {
|
||||||
|
file_name: "mediapipe/tasks/testdata/vision/face_blendshapes.tflite"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input_stream: "LANDMARKS:landmarks"
|
||||||
|
input_stream: "IMAGE_SIZE:image_size"
|
||||||
|
)pb"));
|
||||||
|
|
||||||
|
std::string expected_graph_contents;
|
||||||
|
MP_ASSERT_OK(file::GetContents(
|
||||||
|
file::JoinPath("./", kTestDataDirectory, kGeneratedGraph),
|
||||||
|
&expected_graph_contents));
|
||||||
|
auto expected_graph = mediapipe::ParseTextProtoOrDie<CalculatorGraphConfig>(
|
||||||
|
expected_graph_contents);
|
||||||
|
EXPECT_THAT(actual_graph, testing::proto::IgnoringRepeatedFieldOrdering(
|
||||||
|
testing::EqualsProto(expected_graph)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace face_landmarker
|
||||||
|
} // namespace vision
|
||||||
|
} // namespace tasks
|
||||||
|
} // namespace mediapipe
|
|
@ -20,6 +20,16 @@ package(default_visibility = [
|
||||||
|
|
||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
|
|
||||||
|
mediapipe_proto_library(
|
||||||
|
name = "face_blendshapes_graph_options_proto",
|
||||||
|
srcs = ["face_blendshapes_graph_options.proto"],
|
||||||
|
deps = [
|
||||||
|
"//mediapipe/framework:calculator_options_proto",
|
||||||
|
"//mediapipe/framework:calculator_proto",
|
||||||
|
"//mediapipe/tasks/cc/core/proto:base_options_proto",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
mediapipe_proto_library(
|
mediapipe_proto_library(
|
||||||
name = "face_landmarks_detector_graph_options_proto",
|
name = "face_landmarks_detector_graph_options_proto",
|
||||||
srcs = ["face_landmarks_detector_graph_options.proto"],
|
srcs = ["face_landmarks_detector_graph_options.proto"],
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/* Copyright 2023 The MediaPipe Authors. All Rights Reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
==============================================================================*/
|
||||||
|
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
package mediapipe.tasks.vision.face_landmarker.proto;
|
||||||
|
|
||||||
|
import "mediapipe/framework/calculator.proto";
|
||||||
|
import "mediapipe/framework/calculator_options.proto";
|
||||||
|
import "mediapipe/tasks/cc/core/proto/base_options.proto";
|
||||||
|
|
||||||
|
option java_package = "com.google.mediapipe.tasks.vision.facelandmarker.proto";
|
||||||
|
option java_outer_classname = "FaceBlendshapesGraphOptionsProto";
|
||||||
|
|
||||||
|
message FaceBlendshapesGraphOptions {
|
||||||
|
extend mediapipe.CalculatorOptions {
|
||||||
|
optional FaceBlendshapesGraphOptions ext = 508981768;
|
||||||
|
}
|
||||||
|
// Base options for configuring Task library, such as specifying the TfLite
|
||||||
|
// model file with metadata, accelerator options, etc.
|
||||||
|
optional core.proto.BaseOptions base_options = 1;
|
||||||
|
}
|
878
mediapipe/tasks/testdata/vision/face_blendshapes_generated_graph.pbtxt
vendored
Normal file
878
mediapipe/tasks/testdata/vision/face_blendshapes_generated_graph.pbtxt
vendored
Normal file
|
@ -0,0 +1,878 @@
|
||||||
|
node {
|
||||||
|
name: "mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__SplitNormalizedLandmarkListCalculator"
|
||||||
|
calculator: "SplitNormalizedLandmarkListCalculator"
|
||||||
|
input_stream: "landmarks"
|
||||||
|
output_stream: "mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph____stream_2"
|
||||||
|
options {
|
||||||
|
[mediapipe.SplitVectorCalculatorOptions.ext] {
|
||||||
|
ranges {
|
||||||
|
begin: 0
|
||||||
|
end: 1
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 1
|
||||||
|
end: 2
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 4
|
||||||
|
end: 5
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 5
|
||||||
|
end: 6
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 6
|
||||||
|
end: 7
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 7
|
||||||
|
end: 8
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 8
|
||||||
|
end: 9
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 10
|
||||||
|
end: 11
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 13
|
||||||
|
end: 14
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 14
|
||||||
|
end: 15
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 17
|
||||||
|
end: 18
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 21
|
||||||
|
end: 22
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 33
|
||||||
|
end: 34
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 37
|
||||||
|
end: 38
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 39
|
||||||
|
end: 40
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 40
|
||||||
|
end: 41
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 46
|
||||||
|
end: 47
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 52
|
||||||
|
end: 53
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 53
|
||||||
|
end: 54
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 54
|
||||||
|
end: 55
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 55
|
||||||
|
end: 56
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 58
|
||||||
|
end: 59
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 61
|
||||||
|
end: 62
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 63
|
||||||
|
end: 64
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 65
|
||||||
|
end: 66
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 66
|
||||||
|
end: 67
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 67
|
||||||
|
end: 68
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 70
|
||||||
|
end: 71
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 78
|
||||||
|
end: 79
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 80
|
||||||
|
end: 81
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 81
|
||||||
|
end: 82
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 82
|
||||||
|
end: 83
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 84
|
||||||
|
end: 85
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 87
|
||||||
|
end: 88
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 88
|
||||||
|
end: 89
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 91
|
||||||
|
end: 92
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 93
|
||||||
|
end: 94
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 95
|
||||||
|
end: 96
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 103
|
||||||
|
end: 104
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 105
|
||||||
|
end: 106
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 107
|
||||||
|
end: 108
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 109
|
||||||
|
end: 110
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 127
|
||||||
|
end: 128
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 132
|
||||||
|
end: 133
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 133
|
||||||
|
end: 134
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 136
|
||||||
|
end: 137
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 144
|
||||||
|
end: 145
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 145
|
||||||
|
end: 146
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 146
|
||||||
|
end: 147
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 148
|
||||||
|
end: 149
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 149
|
||||||
|
end: 150
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 150
|
||||||
|
end: 151
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 152
|
||||||
|
end: 153
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 153
|
||||||
|
end: 154
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 154
|
||||||
|
end: 155
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 155
|
||||||
|
end: 156
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 157
|
||||||
|
end: 158
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 158
|
||||||
|
end: 159
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 159
|
||||||
|
end: 160
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 160
|
||||||
|
end: 161
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 161
|
||||||
|
end: 162
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 162
|
||||||
|
end: 163
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 163
|
||||||
|
end: 164
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 168
|
||||||
|
end: 169
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 172
|
||||||
|
end: 173
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 173
|
||||||
|
end: 174
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 176
|
||||||
|
end: 177
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 178
|
||||||
|
end: 179
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 181
|
||||||
|
end: 182
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 185
|
||||||
|
end: 186
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 191
|
||||||
|
end: 192
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 195
|
||||||
|
end: 196
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 197
|
||||||
|
end: 198
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 234
|
||||||
|
end: 235
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 246
|
||||||
|
end: 247
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 249
|
||||||
|
end: 250
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 251
|
||||||
|
end: 252
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 263
|
||||||
|
end: 264
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 267
|
||||||
|
end: 268
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 269
|
||||||
|
end: 270
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 270
|
||||||
|
end: 271
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 276
|
||||||
|
end: 277
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 282
|
||||||
|
end: 283
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 283
|
||||||
|
end: 284
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 284
|
||||||
|
end: 285
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 285
|
||||||
|
end: 286
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 288
|
||||||
|
end: 289
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 291
|
||||||
|
end: 292
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 293
|
||||||
|
end: 294
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 295
|
||||||
|
end: 296
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 296
|
||||||
|
end: 297
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 297
|
||||||
|
end: 298
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 300
|
||||||
|
end: 301
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 308
|
||||||
|
end: 309
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 310
|
||||||
|
end: 311
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 311
|
||||||
|
end: 312
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 312
|
||||||
|
end: 313
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 314
|
||||||
|
end: 315
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 317
|
||||||
|
end: 318
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 318
|
||||||
|
end: 319
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 321
|
||||||
|
end: 322
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 323
|
||||||
|
end: 324
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 324
|
||||||
|
end: 325
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 332
|
||||||
|
end: 333
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 334
|
||||||
|
end: 335
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 336
|
||||||
|
end: 337
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 338
|
||||||
|
end: 339
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 356
|
||||||
|
end: 357
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 361
|
||||||
|
end: 362
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 362
|
||||||
|
end: 363
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 365
|
||||||
|
end: 366
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 373
|
||||||
|
end: 374
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 374
|
||||||
|
end: 375
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 375
|
||||||
|
end: 376
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 377
|
||||||
|
end: 378
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 378
|
||||||
|
end: 379
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 379
|
||||||
|
end: 380
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 380
|
||||||
|
end: 381
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 381
|
||||||
|
end: 382
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 382
|
||||||
|
end: 383
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 384
|
||||||
|
end: 385
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 385
|
||||||
|
end: 386
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 386
|
||||||
|
end: 387
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 387
|
||||||
|
end: 388
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 388
|
||||||
|
end: 389
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 389
|
||||||
|
end: 390
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 390
|
||||||
|
end: 391
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 397
|
||||||
|
end: 398
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 398
|
||||||
|
end: 399
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 400
|
||||||
|
end: 401
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 402
|
||||||
|
end: 403
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 405
|
||||||
|
end: 406
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 409
|
||||||
|
end: 410
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 415
|
||||||
|
end: 416
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 454
|
||||||
|
end: 455
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 466
|
||||||
|
end: 467
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 468
|
||||||
|
end: 469
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 469
|
||||||
|
end: 470
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 470
|
||||||
|
end: 471
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 471
|
||||||
|
end: 472
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 472
|
||||||
|
end: 473
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 473
|
||||||
|
end: 474
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 474
|
||||||
|
end: 475
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 475
|
||||||
|
end: 476
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 476
|
||||||
|
end: 477
|
||||||
|
}
|
||||||
|
ranges {
|
||||||
|
begin: 477
|
||||||
|
end: 478
|
||||||
|
}
|
||||||
|
combine_outputs: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node {
|
||||||
|
name: "mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__LandmarksToTensorCalculator"
|
||||||
|
calculator: "LandmarksToTensorCalculator"
|
||||||
|
input_stream: "IMAGE_SIZE:image_size"
|
||||||
|
input_stream: "NORM_LANDMARKS:mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph____stream_2"
|
||||||
|
output_stream: "TENSORS:mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph____stream_3"
|
||||||
|
options {
|
||||||
|
[mediapipe.LandmarksToTensorCalculatorOptions.ext] {
|
||||||
|
attributes: X
|
||||||
|
attributes: Y
|
||||||
|
flatten: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node {
|
||||||
|
name: "mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__mediapipe_tasks_core_inferencesubgraph__ModelResourcesCalculator"
|
||||||
|
calculator: "ModelResourcesCalculator"
|
||||||
|
output_side_packet: "METADATA_EXTRACTOR:mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__mediapipe_tasks_core_inferencesubgraph____side_packet_1"
|
||||||
|
output_side_packet: "MODEL:mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__mediapipe_tasks_core_inferencesubgraph____side_packet_2"
|
||||||
|
output_side_packet: "OP_RESOLVER:mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__mediapipe_tasks_core_inferencesubgraph____side_packet_3"
|
||||||
|
options {
|
||||||
|
[mediapipe.tasks.core.proto.ModelResourcesCalculatorOptions.ext] {
|
||||||
|
model_file {
|
||||||
|
file_name: "mediapipe/tasks/testdata/vision/face_blendshapes.tflite"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node {
|
||||||
|
name: "mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__mediapipe_tasks_core_inferencesubgraph__inferencecalculator__mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__mediapipe_tasks_core_inferencesubgraph__InferenceCalculator"
|
||||||
|
calculator: "InferenceCalculatorCpu"
|
||||||
|
input_stream: "TENSORS:mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph____stream_3"
|
||||||
|
output_stream: "TENSORS:mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph____stream_4"
|
||||||
|
input_side_packet: "MODEL:mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__mediapipe_tasks_core_inferencesubgraph____side_packet_2"
|
||||||
|
input_side_packet: "OP_RESOLVER:mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__mediapipe_tasks_core_inferencesubgraph____side_packet_3"
|
||||||
|
options {
|
||||||
|
[mediapipe.InferenceCalculatorOptions.ext] {
|
||||||
|
delegate {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node {
|
||||||
|
name: "mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__SplitTensorVectorCalculator"
|
||||||
|
calculator: "SplitTensorVectorCalculator"
|
||||||
|
input_stream: "mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph____stream_4"
|
||||||
|
output_stream: "mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph____stream_5"
|
||||||
|
options {
|
||||||
|
[mediapipe.SplitVectorCalculatorOptions.ext] {
|
||||||
|
ranges {
|
||||||
|
begin: 0
|
||||||
|
end: 1
|
||||||
|
}
|
||||||
|
combine_outputs: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node {
|
||||||
|
name: "mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph__TensorsToClassificationCalculator"
|
||||||
|
calculator: "TensorsToClassificationCalculator"
|
||||||
|
input_stream: "TENSORS:mediapipe_tasks_vision_face_landmarker_faceblendshapesgraph____stream_5"
|
||||||
|
output_stream: "CLASSIFICATIONS:blendshapes"
|
||||||
|
options {
|
||||||
|
[mediapipe.TensorsToClassificationCalculatorOptions.ext] {
|
||||||
|
min_score_threshold: -1
|
||||||
|
top_k: 0
|
||||||
|
label_map {
|
||||||
|
entries {
|
||||||
|
id: 0
|
||||||
|
label: "_neutral"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 1
|
||||||
|
label: "browDownLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 2
|
||||||
|
label: "browDownRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 3
|
||||||
|
label: "browInnerUp"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 4
|
||||||
|
label: "browOuterUpLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 5
|
||||||
|
label: "browOuterUpRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 6
|
||||||
|
label: "cheekPuff"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 7
|
||||||
|
label: "cheekSquintLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 8
|
||||||
|
label: "cheekSquintRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 9
|
||||||
|
label: "eyeBlinkLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 10
|
||||||
|
label: "eyeBlinkRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 11
|
||||||
|
label: "eyeLookDownLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 12
|
||||||
|
label: "eyeLookDownRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 13
|
||||||
|
label: "eyeLookInLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 14
|
||||||
|
label: "eyeLookInRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 15
|
||||||
|
label: "eyeLookOutLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 16
|
||||||
|
label: "eyeLookOutRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 17
|
||||||
|
label: "eyeLookUpLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 18
|
||||||
|
label: "eyeLookUpRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 19
|
||||||
|
label: "eyeSquintLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 20
|
||||||
|
label: "eyeSquintRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 21
|
||||||
|
label: "eyeWideLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 22
|
||||||
|
label: "eyeWideRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 23
|
||||||
|
label: "jawForward"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 24
|
||||||
|
label: "jawLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 25
|
||||||
|
label: "jawOpen"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 26
|
||||||
|
label: "jawRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 27
|
||||||
|
label: "mouthClose"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 28
|
||||||
|
label: "mouthDimpleLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 29
|
||||||
|
label: "mouthDimpleRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 30
|
||||||
|
label: "mouthFrownLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 31
|
||||||
|
label: "mouthFrownRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 32
|
||||||
|
label: "mouthFunnel"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 33
|
||||||
|
label: "mouthLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 34
|
||||||
|
label: "mouthLowerDownLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 35
|
||||||
|
label: "mouthLowerDownRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 36
|
||||||
|
label: "mouthPressLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 37
|
||||||
|
label: "mouthPressRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 38
|
||||||
|
label: "mouthPucker"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 39
|
||||||
|
label: "mouthRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 40
|
||||||
|
label: "mouthRollLower"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 41
|
||||||
|
label: "mouthRollUpper"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 42
|
||||||
|
label: "mouthShrugLower"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 43
|
||||||
|
label: "mouthShrugUpper"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 44
|
||||||
|
label: "mouthSmileLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 45
|
||||||
|
label: "mouthSmileRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 46
|
||||||
|
label: "mouthStretchLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 47
|
||||||
|
label: "mouthStretchRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 48
|
||||||
|
label: "mouthUpperUpLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 49
|
||||||
|
label: "mouthUpperUpRight"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 50
|
||||||
|
label: "noseSneerLeft"
|
||||||
|
}
|
||||||
|
entries {
|
||||||
|
id: 51
|
||||||
|
label: "noseSneerRight"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input_stream: "LANDMARKS:landmarks"
|
||||||
|
input_stream: "IMAGE_SIZE:image_size"
|
||||||
|
executor {
|
||||||
|
}
|
3346
mediapipe/tasks/testdata/vision/face_blendshapes_in_landmarks.prototxt
vendored
Normal file
3346
mediapipe/tasks/testdata/vision/face_blendshapes_in_landmarks.prototxt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
260
mediapipe/tasks/testdata/vision/face_blendshapes_out.prototxt
vendored
Normal file
260
mediapipe/tasks/testdata/vision/face_blendshapes_out.prototxt
vendored
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
classification {
|
||||||
|
index: 0
|
||||||
|
score: 3.0398707e-05
|
||||||
|
label: "_neutral"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 1
|
||||||
|
score: 0.9075446
|
||||||
|
label: "browDownLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 2
|
||||||
|
score: 0.88084334
|
||||||
|
label: "browDownRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 3
|
||||||
|
score: 8.574165e-05
|
||||||
|
label: "browInnerUp"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 4
|
||||||
|
score: 0.00025488975
|
||||||
|
label: "browOuterUpLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 5
|
||||||
|
score: 0.0003774864
|
||||||
|
label: "browOuterUpRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 6
|
||||||
|
score: 0.0013324458
|
||||||
|
label: "cheekPuff"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 7
|
||||||
|
score: 3.3356114e-06
|
||||||
|
label: "cheekSquintLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 8
|
||||||
|
score: 3.486574e-06
|
||||||
|
label: "cheekSquintRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 9
|
||||||
|
score: 0.23493542
|
||||||
|
label: "eyeBlinkLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 10
|
||||||
|
score: 0.25156906
|
||||||
|
label: "eyeBlinkRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 11
|
||||||
|
score: 0.31935102
|
||||||
|
label: "eyeLookDownLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 12
|
||||||
|
score: 0.3578726
|
||||||
|
label: "eyeLookDownRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 13
|
||||||
|
score: 0.040764388
|
||||||
|
label: "eyeLookInLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 14
|
||||||
|
score: 0.10176937
|
||||||
|
label: "eyeLookInRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 15
|
||||||
|
score: 0.13951905
|
||||||
|
label: "eyeLookOutLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 16
|
||||||
|
score: 0.08599486
|
||||||
|
label: "eyeLookOutRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 17
|
||||||
|
score: 0.04357939
|
||||||
|
label: "eyeLookUpLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 18
|
||||||
|
score: 0.039808873
|
||||||
|
label: "eyeLookUpRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 19
|
||||||
|
score: 0.71037096
|
||||||
|
label: "eyeSquintLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 20
|
||||||
|
score: 0.5613919
|
||||||
|
label: "eyeSquintRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 21
|
||||||
|
score: 0.0035762936
|
||||||
|
label: "eyeWideLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 22
|
||||||
|
score: 0.0046946923
|
||||||
|
label: "eyeWideRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 23
|
||||||
|
score: 0.0015334645
|
||||||
|
label: "jawForward"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 24
|
||||||
|
score: 0.0015781156
|
||||||
|
label: "jawLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 25
|
||||||
|
score: 0.1825222
|
||||||
|
label: "jawOpen"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 26
|
||||||
|
score: 0.00022096233
|
||||||
|
label: "jawRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 27
|
||||||
|
score: 0.04180384
|
||||||
|
label: "mouthClose"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 28
|
||||||
|
score: 0.03450827
|
||||||
|
label: "mouthDimpleLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 29
|
||||||
|
score: 0.02150588
|
||||||
|
label: "mouthDimpleRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 30
|
||||||
|
score: 0.0004071877
|
||||||
|
label: "mouthFrownLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 31
|
||||||
|
score: 0.00041903765
|
||||||
|
label: "mouthFrownRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 32
|
||||||
|
score: 0.006162456
|
||||||
|
label: "mouthFunnel"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 33
|
||||||
|
score: 0.0007518647
|
||||||
|
label: "mouthLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 34
|
||||||
|
score: 0.020578554
|
||||||
|
label: "mouthLowerDownLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 35
|
||||||
|
score: 0.06688861
|
||||||
|
label: "mouthLowerDownRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 36
|
||||||
|
score: 0.21384144
|
||||||
|
label: "mouthPressLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 37
|
||||||
|
score: 0.12757207
|
||||||
|
label: "mouthPressRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 38
|
||||||
|
score: 0.0037631108
|
||||||
|
label: "mouthPucker"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 39
|
||||||
|
score: 0.0017571376
|
||||||
|
label: "mouthRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 40
|
||||||
|
score: 0.017397188
|
||||||
|
label: "mouthRollLower"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 41
|
||||||
|
score: 0.073125295
|
||||||
|
label: "mouthRollUpper"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 42
|
||||||
|
score: 0.009962141
|
||||||
|
label: "mouthShrugLower"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 43
|
||||||
|
score: 0.006196939
|
||||||
|
label: "mouthShrugUpper"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 44
|
||||||
|
score: 0.9412662
|
||||||
|
label: "mouthSmileLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 45
|
||||||
|
score: 0.9020016
|
||||||
|
label: "mouthSmileRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 46
|
||||||
|
score: 0.054742802
|
||||||
|
label: "mouthStretchLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 47
|
||||||
|
score: 0.080990806
|
||||||
|
label: "mouthStretchRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 48
|
||||||
|
score: 0.7372297
|
||||||
|
label: "mouthUpperUpLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 49
|
||||||
|
score: 0.69999576
|
||||||
|
label: "mouthUpperUpRight"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 50
|
||||||
|
score: 3.5180938e-07
|
||||||
|
label: "noseSneerLeft"
|
||||||
|
}
|
||||||
|
classification {
|
||||||
|
index: 51
|
||||||
|
score: 8.41376e-06
|
||||||
|
label: "noseSneerRight"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user