diff --git a/mediapipe/tasks/cc/vision/face_landmarker/BUILD b/mediapipe/tasks/cc/vision/face_landmarker/BUILD index dbdcfa6a6..a5b8508aa 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/BUILD +++ b/mediapipe/tasks/cc/vision/face_landmarker/BUILD @@ -18,6 +18,27 @@ package(default_visibility = [ licenses(["notice"]) +cc_library( + name = "tensors_to_face_landmarks_graph", + srcs = ["tensors_to_face_landmarks_graph.cc"], + deps = [ + "//mediapipe/calculators/core:split_vector_calculator", + "//mediapipe/calculators/core:split_vector_calculator_cc_proto", + "//mediapipe/calculators/tensor:tensors_to_landmarks_calculator", + "//mediapipe/calculators/tensor:tensors_to_landmarks_calculator_cc_proto", + "//mediapipe/calculators/util:landmarks_refinement_calculator", + "//mediapipe/calculators/util:landmarks_refinement_calculator_cc_proto", + "//mediapipe/framework:calculator_cc_proto", + "//mediapipe/framework:calculator_framework", + "//mediapipe/framework:subgraph", + "//mediapipe/framework/api2:builder", + "//mediapipe/framework/formats:landmark_cc_proto", + "//mediapipe/framework/formats:tensor", + "//mediapipe/tasks/cc/vision/face_landmarker/proto:tensors_to_face_landmarks_graph_options_cc_proto", + ], + alwayslink = 1, +) + cc_library( name = "face_blendshapes_graph", srcs = ["face_blendshapes_graph.cc"], @@ -48,6 +69,7 @@ cc_library( name = "face_landmarks_detector_graph", srcs = ["face_landmarks_detector_graph.cc"], deps = [ + ":tensors_to_face_landmarks_graph", "//mediapipe/calculators/core:begin_loop_calculator", "//mediapipe/calculators/core:end_loop_calculator", "//mediapipe/calculators/core:split_vector_calculator", @@ -80,6 +102,7 @@ cc_library( "//mediapipe/tasks/cc/core:model_task_graph", "//mediapipe/tasks/cc/core:utils", "//mediapipe/tasks/cc/vision/face_landmarker/proto:face_landmarks_detector_graph_options_cc_proto", + "//mediapipe/tasks/cc/vision/face_landmarker/proto:tensors_to_face_landmarks_graph_options_cc_proto", "//mediapipe/tasks/cc/vision/utils:image_tensor_specs", ], alwayslink = 1, diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc index 7a2549b92..61ab45fd5 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc @@ -37,6 +37,7 @@ limitations under the License. #include "mediapipe/tasks/cc/core/model_task_graph.h" #include "mediapipe/tasks/cc/core/utils.h" #include "mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options.pb.h" +#include "mediapipe/tasks/cc/vision/face_landmarker/proto/tensors_to_face_landmarks_graph_options.pb.h" #include "mediapipe/tasks/cc/vision/utils/image_tensor_specs.h" namespace mediapipe { @@ -72,8 +73,10 @@ constexpr char kBatchEndTag[] = "BATCH_END"; constexpr char kItemTag[] = "ITEM"; constexpr char kDetectionTag[] = "DETECTION"; -constexpr int kLandmarksNum = 468; -constexpr int kModelOutputTensorSplitNum = 2; +// a landmarks tensor and a scores tensor +constexpr int kFaceLandmarksOutputTensorsNum = 2; +// 6 landmarks tensors and a scores tensor. +constexpr int kAttentionMeshOutputTensorsNum = 7; struct SingleFaceLandmarksOutputs { Stream landmarks; @@ -104,18 +107,28 @@ absl::Status SanityCheckOptions( // Split face landmark detection model output tensor into two parts, // representing landmarks and face presence scores. void ConfigureSplitTensorVectorCalculator( - mediapipe::SplitVectorCalculatorOptions* options) { - for (int i = 0; i < kModelOutputTensorSplitNum; ++i) { + bool is_attention_model, mediapipe::SplitVectorCalculatorOptions* options) { + if (is_attention_model) { auto* range = options->add_ranges(); - range->set_begin(i); - range->set_end(i + 1); + range->set_begin(0); + range->set_end(kAttentionMeshOutputTensorsNum - 1); + range = options->add_ranges(); + range->set_begin(kAttentionMeshOutputTensorsNum - 1); + range->set_end(kAttentionMeshOutputTensorsNum); + } else { + auto* range = options->add_ranges(); + range->set_begin(0); + range->set_end(kFaceLandmarksOutputTensorsNum - 1); + range = options->add_ranges(); + range->set_begin(kFaceLandmarksOutputTensorsNum - 1); + range->set_end(kFaceLandmarksOutputTensorsNum); } } -void ConfigureTensorsToLandmarksCalculator( - const ImageTensorSpecs& input_image_tensor_spec, - mediapipe::TensorsToLandmarksCalculatorOptions* options) { - options->set_num_landmarks(kLandmarksNum); +void ConfigureTensorsToFaceLandmarksGraph( + const ImageTensorSpecs& input_image_tensor_spec, bool is_attention_model, + proto::TensorsToFaceLandmarksGraphOptions* options) { + options->set_is_attention_model(is_attention_model); options->set_input_image_height(input_image_tensor_spec.image_height); options->set_input_image_width(input_image_tensor_spec.image_width); } @@ -138,6 +151,12 @@ void ConfigureFaceRectTransformationCalculator( options->set_square_long(true); } +bool IsAttentionModel(const core::ModelResources& model_resources) { + const auto* model = model_resources.GetTfLiteModel(); + const auto* primary_subgraph = (*model->subgraphs())[0]; + return primary_subgraph->outputs()->size() == kAttentionMeshOutputTensorsNum; +} + } // namespace // A "mediapipe.tasks.vision.face_landmarker.SingleFaceLandmarksDetectorGraph" @@ -246,8 +265,10 @@ class SingleFaceLandmarksDetectorGraph : public core::ModelTaskGraph { auto output_tensors = inference.Out(kTensorsTag); // Split model output tensors to multiple streams. + bool is_attention_model = IsAttentionModel(model_resources); auto& split_tensors_vector = graph.AddNode("SplitTensorVectorCalculator"); ConfigureSplitTensorVectorCalculator( + is_attention_model, &split_tensors_vector .GetOptions()); output_tensors >> split_tensors_vector.In(""); @@ -256,15 +277,16 @@ class SingleFaceLandmarksDetectorGraph : public core::ModelTaskGraph { // Decodes the landmark tensors into a list of landmarks, where the landmark // coordinates are normalized by the size of the input image to the model. - auto& tensors_to_landmarks = graph.AddNode("TensorsToLandmarksCalculator"); ASSIGN_OR_RETURN(auto image_tensor_specs, vision::BuildInputImageTensorSpecs(model_resources)); - ConfigureTensorsToLandmarksCalculator( - image_tensor_specs, - &tensors_to_landmarks - .GetOptions()); - landmark_tensors >> tensors_to_landmarks.In(kTensorsTag); - auto landmarks = tensors_to_landmarks.Out(kNormLandmarksTag); + auto& tensors_to_face_landmarks = graph.AddNode( + "mediapipe.tasks.vision.face_landmarker.TensorsToFaceLandmarksGraph"); + ConfigureTensorsToFaceLandmarksGraph( + image_tensor_specs, is_attention_model, + &tensors_to_face_landmarks + .GetOptions()); + landmark_tensors >> tensors_to_face_landmarks.In(kTensorsTag); + auto landmarks = tensors_to_face_landmarks.Out(kNormLandmarksTag); // Converts the presence flag tensor into a float that represents the // confidence score of face presence. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc index fb3c50c5b..baebfdd3b 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc @@ -29,6 +29,7 @@ limitations under the License. #include "mediapipe/framework/port/file_helpers.h" #include "mediapipe/framework/port/gmock.h" #include "mediapipe/framework/port/gtest.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/proto/external_file.pb.h" #include "mediapipe/tasks/cc/core/task_runner.h" @@ -61,10 +62,14 @@ using ::testing::proto::Partially; constexpr char kTestDataDirectory[] = "/mediapipe/tasks/testdata/vision/"; constexpr char kFaceLandmarksDetectionModel[] = "face_landmark.tflite"; +constexpr char kFaceLandmarksDetectionWithAttentionModel[] = + "face_landmark_with_attention.tflite"; constexpr char kPortraitImageName[] = "portrait.jpg"; constexpr char kCatImageName[] = "cat.jpg"; constexpr char kPortraitExpectedFaceLandamrksName[] = "portrait_expected_face_landmarks.pbtxt"; +constexpr char kPortraitExpectedFaceLandamrksWithAttentionName[] = + "portrait_expected_face_landmarks_with_attention.pbtxt"; constexpr char kImageTag[] = "IMAGE"; constexpr char kImageName[] = "image"; @@ -117,8 +122,7 @@ absl::StatusOr> CreateSingleFaceLandmarksTaskRunner( graph[Output(kFaceRectNextFrameTag)]; return TaskRunner::Create( - graph.GetConfig(), - absl::make_unique()); + graph.GetConfig(), absl::make_unique()); } // Helper function to create a Multi Face Landmark TaskRunner. @@ -154,8 +158,7 @@ absl::StatusOr> CreateMultiFaceLandmarksTaskRunner( graph[Output>(kFaceRectsNextFrameTag)]; return TaskRunner::Create( - graph.GetConfig(), - absl::make_unique()); + graph.GetConfig(), absl::make_unique()); } NormalizedLandmarkList GetExpectedLandmarkList(absl::string_view filename) { @@ -280,14 +283,24 @@ TEST_P(MultiFaceLandmarksDetectionTest, Succeeds) { INSTANTIATE_TEST_SUITE_P( FaceLandmarksDetectionTest, SingleFaceLandmarksDetectionTest, Values(SingeFaceTestParams{ - /* test_name= */ "Portrait", - /*input_model_name= */ kFaceLandmarksDetectionModel, - /*test_image_name=*/kPortraitImageName, - /*norm_rect= */ MakeNormRect(0.4987, 0.2211, 0.2877, 0.2303, 0), - /*expected_presence = */ true, - /*expected_landmarks = */ - GetExpectedLandmarkList(kPortraitExpectedFaceLandamrksName), - /*landmarks_diff_threshold = */ kFractionDiff}), + /* test_name= */ "Portrait", + /*input_model_name= */ kFaceLandmarksDetectionModel, + /*test_image_name=*/kPortraitImageName, + /*norm_rect= */ MakeNormRect(0.4987, 0.2211, 0.2877, 0.2303, 0), + /*expected_presence = */ true, + /*expected_landmarks = */ + GetExpectedLandmarkList(kPortraitExpectedFaceLandamrksName), + /*landmarks_diff_threshold = */ kFractionDiff}, + SingeFaceTestParams{ + /* test_name= */ "PortraitWithAttention", + /*input_model_name= */ kFaceLandmarksDetectionWithAttentionModel, + /*test_image_name=*/kPortraitImageName, + /*norm_rect= */ MakeNormRect(0.4987, 0.2211, 0.2877, 0.2303, 0), + /*expected_presence = */ true, + /*expected_landmarks = */ + GetExpectedLandmarkList( + kPortraitExpectedFaceLandamrksWithAttentionName), + /*landmarks_diff_threshold = */ kFractionDiff}), [](const TestParamInfo& info) { return info.param.test_name; }); @@ -304,6 +317,16 @@ INSTANTIATE_TEST_SUITE_P( /*expected_landmarks_list = */ {{GetExpectedLandmarkList(kPortraitExpectedFaceLandamrksName)}}, /*landmarks_diff_threshold = */ kFractionDiff}, + MultiFaceTestParams{ + /* test_name= */ "PortraitWithAttention", + /*input_model_name= */ kFaceLandmarksDetectionWithAttentionModel, + /*test_image_name=*/kPortraitImageName, + /*norm_rects= */ {MakeNormRect(0.4987, 0.2211, 0.2877, 0.2303, 0)}, + /*expected_presence = */ {true}, + /*expected_landmarks_list = */ + {{GetExpectedLandmarkList( + kPortraitExpectedFaceLandamrksWithAttentionName)}}, + /*landmarks_diff_threshold = */ kFractionDiff}, MultiFaceTestParams{ /* test_name= */ "NoFace", /*input_model_name= */ kFaceLandmarksDetectionModel, diff --git a/mediapipe/tasks/cc/vision/face_landmarker/proto/BUILD b/mediapipe/tasks/cc/vision/face_landmarker/proto/BUILD index dfb34264d..fe8e8353e 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/proto/BUILD +++ b/mediapipe/tasks/cc/vision/face_landmarker/proto/BUILD @@ -39,3 +39,13 @@ mediapipe_proto_library( "//mediapipe/tasks/cc/core/proto:base_options_proto", ], ) + +mediapipe_proto_library( + name = "tensors_to_face_landmarks_graph_options_proto", + srcs = ["tensors_to_face_landmarks_graph_options.proto"], + deps = [ + "//mediapipe/calculators/tensor:tensors_to_landmarks_calculator_proto", + "//mediapipe/framework:calculator_options_proto", + "//mediapipe/framework:calculator_proto", + ], +) diff --git a/mediapipe/tasks/cc/vision/face_landmarker/proto/tensors_to_face_landmarks_graph_options.proto b/mediapipe/tasks/cc/vision/face_landmarker/proto/tensors_to_face_landmarks_graph_options.proto new file mode 100644 index 000000000..0ebecf002 --- /dev/null +++ b/mediapipe/tasks/cc/vision/face_landmarker/proto/tensors_to_face_landmarks_graph_options.proto @@ -0,0 +1,35 @@ +/* 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"; + +message TensorsToFaceLandmarksGraphOptions { + extend mediapipe.CalculatorOptions { + optional TensorsToFaceLandmarksGraphOptions ext = 509621260; + } + + // Whether the landmarks model is with attention on lips and eyes. Attention + // provides more accuracy on lips and eye regions as well as iris landmarks. + optional bool is_attention_model = 1 [default = false]; + + optional int32 input_image_width = 2; + + optional int32 input_image_height = 3; +} diff --git a/mediapipe/tasks/cc/vision/face_landmarker/tensors_to_face_landmarks_graph.cc b/mediapipe/tasks/cc/vision/face_landmarker/tensors_to_face_landmarks_graph.cc new file mode 100644 index 000000000..b93ee925e --- /dev/null +++ b/mediapipe/tasks/cc/vision/face_landmarker/tensors_to_face_landmarks_graph.cc @@ -0,0 +1,373 @@ +/* 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 +#include +#include +#include +#include + +#include "mediapipe/calculators/core/split_vector_calculator.pb.h" +#include "mediapipe/calculators/tensor/tensors_to_landmarks_calculator.pb.h" +#include "mediapipe/calculators/util/landmarks_refinement_calculator.pb.h" +#include "mediapipe/framework/api2/builder.h" +#include "mediapipe/framework/calculator.pb.h" +#include "mediapipe/framework/calculator_framework.h" +#include "mediapipe/framework/formats/landmark.pb.h" +#include "mediapipe/framework/formats/tensor.h" +#include "mediapipe/framework/subgraph.h" +#include "mediapipe/tasks/cc/vision/face_landmarker/proto/tensors_to_face_landmarks_graph_options.pb.h" + +namespace mediapipe { +namespace tasks { +namespace vision { +namespace face_landmarker { +namespace { + +using ::mediapipe::api2::builder::Graph; +using ::mediapipe::api2::builder::SidePacket; +using ::mediapipe::api2::builder::Stream; + +constexpr char kTensorsTag[] = "TENSORS"; +constexpr char kNormLandmarksTag[] = "NORM_LANDMARKS"; +constexpr char kLandmarksTag[] = "LANDMARKS"; +constexpr char kRefinedLandmarksTag[] = "REFINED_LANDMARKS"; +constexpr int kAttentionModelSplitNum = 6; +constexpr int kMeshLandmarksNum = 468; +constexpr int kLipsLandmarksNum = 80; +constexpr int kEyeLandmarksNum = 71; +constexpr int kIrisLandmarksNum = 5; +constexpr int kContoursNumForIrisAvg = 16; + +// TODO When model metadata for face detector is ready, move the +// index mapping to metadata. +constexpr std::array kMeshLandmarksIndicesMapping{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, + 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467}; + +constexpr std::array kLipsLandmarksIndicesMapping{ + // Lower outer. + 61, 146, 91, 181, 84, 17, 314, 405, 321, 375, 291, + // Upper outer (excluding corners). + 185, 40, 39, 37, 0, 267, 269, 270, 409, + // Lower inner. + 78, 95, 88, 178, 87, 14, 317, 402, 318, 324, 308, + // Upper inner (excluding corners). + 191, 80, 81, 82, 13, 312, 311, 310, 415, + // Lower semi-outer. + 76, 77, 90, 180, 85, 16, 315, 404, 320, 307, 306, + // Upper semi-outer (excluding corners). + 184, 74, 73, 72, 11, 302, 303, 304, 408, + // Lower semi-inner. + 62, 96, 89, 179, 86, 15, 316, 403, 319, 325, 292, + // Upper semi-inner (excluding corners). + 183, 42, 41, 38, 12, 268, 271, 272, 407}; + +constexpr std::array kLeftEyeLandmarksIndicesMapping{ + // Lower contour. + 33, 7, 163, 144, 145, 153, 154, 155, 133, + // upper contour (excluding corners). + 246, 161, 160, 159, 158, 157, 173, + // Halo x2 lower contour. + 130, 25, 110, 24, 23, 22, 26, 112, 243, + // Halo x2 upper contour (excluding corners). + 247, 30, 29, 27, 28, 56, 190, + // Halo x3 lower contour. + 226, 31, 228, 229, 230, 231, 232, 233, 244, + // Halo x3 upper contour (excluding corners). + 113, 225, 224, 223, 222, 221, 189, + // Halo x4 upper contour (no lower because of mesh structure) or + // eyebrow inner contour. + 35, 124, 46, 53, 52, 65, + // Halo x5 lower contour. + 143, 111, 117, 118, 119, 120, 121, 128, 245, + // Halo x5 upper contour (excluding corners) or eyebrow outer contour. + 156, 70, 63, 105, 66, 107, 55, 193}; + +constexpr std::array kRightEyeLandmarksIndicesMapping{ + // Lower contour. + 263, 249, 390, 373, 374, 380, 381, 382, 362, + // Upper contour (excluding corners). + 466, 388, 387, 386, 385, 384, 398, + // Halo x2 lower contour. + 359, 255, 339, 254, 253, 252, 256, 341, 463, + // Halo x2 upper contour (excluding corners). + 467, 260, 259, 257, 258, 286, 414, + // Halo x3 lower contour. + 446, 261, 448, 449, 450, 451, 452, 453, 464, + // Halo x3 upper contour (excluding corners). + 342, 445, 444, 443, 442, 441, 413, + // Halo x4 upper contour (no lower because of mesh structure) or + // eyebrow inner contour. + 265, 353, 276, 283, 282, 295, + // Halo x5 lower contour. + 372, 340, 346, 347, 348, 349, 350, 357, 465, + // Halo x5 upper contour (excluding corners) or eyebrow outer contour. + 383, 300, 293, 334, 296, 336, 285, 417}; + +constexpr std::array kLeftIrisLandmarksIndicesMapping{ + // Center. + 468, + // Iris right edge. + 469, + // Iris top edge. + 470, + // Iris left edge. + 471, + // Iris bottom edge. + 472}; + +constexpr std::array kLeftIrisAvgIndices = { + // Lower contour. + 33, 7, 163, 144, 145, 153, 154, 155, 133, + // Upper contour (excluding corners). + 246, 161, 160, 159, 158, 157, 173}; + +constexpr std::array kRightIrisLandmarksIndicesMapping{ + // Center. + 473, + // Iris right edge. + 474, + // Iris top edge. + 475, + // Iris left edge. + 476, + // Iris bottom edge. + 477}; + +constexpr std::array kRightIrisAvgIndices = { + // Lower contour. + 263, 249, 390, 373, 374, 380, 381, 382, 362, + // Upper contour (excluding corners). + 466, 388, 387, 386, 385, 384, 398}; + +void ConfigureSplitTensorVectorCalculator( + mediapipe::SplitVectorCalculatorOptions* options) { + for (int i = 0; i < kAttentionModelSplitNum; ++i) { + auto* range = options->add_ranges(); + range->set_begin(i); + range->set_end(i + 1); + } +} + +Stream ConvertTensorsToLandmarks( + int landmarks_num, int input_image_width, int input_image_height, + Stream> tensors, Graph& graph) { + auto& tensors_to_landmarks = graph.AddNode("TensorsToLandmarksCalculator"); + auto* options = + &tensors_to_landmarks + .GetOptions(); + options->set_num_landmarks(landmarks_num); + options->set_input_image_width(input_image_width); + options->set_input_image_height(input_image_height); + tensors >> tensors_to_landmarks.In(kTensorsTag); + return tensors_to_landmarks.Out(kNormLandmarksTag) + .Cast(); +} + +Stream RefineFaceLandmarks( + Stream mesh_landmarks, + Stream lips_landmarks, + Stream left_eye_landmarks, + Stream right_eye_landmarks, + Stream left_iris_landmarks, + Stream right_iris_landmarks, Graph& graph) { + auto& refine_landmarks = graph.AddNode("LandmarksRefinementCalculator"); + auto& refinement_options = + refine_landmarks + .GetOptions(); + + // Face mesh landmarks. + auto* refinement_for_mesh = refinement_options.add_refinement(); + refinement_for_mesh->mutable_indexes_mapping()->Assign( + kMeshLandmarksIndicesMapping.begin(), kMeshLandmarksIndicesMapping.end()); + refinement_for_mesh->mutable_z_refinement()->mutable_copy(); + + // Lips landmarks. + auto* refinement_for_lips = refinement_options.add_refinement(); + refinement_for_lips->mutable_indexes_mapping()->Assign( + kLipsLandmarksIndicesMapping.begin(), kLipsLandmarksIndicesMapping.end()); + refinement_for_lips->mutable_z_refinement()->mutable_none(); + + // Left eye landmarks. + auto* refinement_for_left_eye = refinement_options.add_refinement(); + refinement_for_left_eye->mutable_indexes_mapping()->Assign( + kLeftEyeLandmarksIndicesMapping.begin(), + kLeftEyeLandmarksIndicesMapping.end()); + refinement_for_left_eye->mutable_z_refinement()->mutable_none(); + + // Right eye landmarks. + auto* refinement_for_right_eye = refinement_options.add_refinement(); + refinement_for_right_eye->mutable_indexes_mapping()->Assign( + kRightEyeLandmarksIndicesMapping.begin(), + kRightEyeLandmarksIndicesMapping.end()); + refinement_for_right_eye->mutable_z_refinement()->mutable_none(); + + // Left iris landmarks. + auto* refinement_for_left_iris = refinement_options.add_refinement(); + refinement_for_left_iris->mutable_indexes_mapping()->Assign( + kLeftIrisLandmarksIndicesMapping.begin(), + kLeftIrisLandmarksIndicesMapping.end()); + refinement_for_left_iris->mutable_z_refinement() + ->mutable_assign_average() + ->mutable_indexes_for_average() + ->Assign(kLeftIrisAvgIndices.begin(), kLeftIrisAvgIndices.end()); + + // Right iris landmarks. + auto* refinement_for_right_iris = refinement_options.add_refinement(); + refinement_for_right_iris->mutable_indexes_mapping()->Assign( + kRightIrisLandmarksIndicesMapping.begin(), + kRightIrisLandmarksIndicesMapping.end()); + refinement_for_right_iris->mutable_z_refinement() + ->mutable_assign_average() + ->mutable_indexes_for_average() + ->Assign(kRightIrisAvgIndices.begin(), kRightIrisAvgIndices.end()); + + mesh_landmarks >> refine_landmarks.In(kLandmarksTag)[0]; + lips_landmarks >> refine_landmarks.In(kLandmarksTag)[1]; + left_eye_landmarks >> refine_landmarks.In(kLandmarksTag)[2]; + right_eye_landmarks >> refine_landmarks.In(kLandmarksTag)[3]; + left_iris_landmarks >> refine_landmarks.In(kLandmarksTag)[4]; + right_iris_landmarks >> refine_landmarks.In(kLandmarksTag)[5]; + return refine_landmarks.Out(kRefinedLandmarksTag) + .Cast(); +} + +} // namespace + +// Graph to transform face landmarks model output tensors into landmarks. +// The graph can support two types of model: regular and attention model with +// refined lips, eye and irises. +// +// Inputs: +// TENSORS - std::vector +// Landmarks tensors to be transformed. If regular model, a vector of single +// Tensor is expected. If a model with attention, a vector of 6 Tensors is +// expected. +// +// Outputs: +// NORM_LANDMARKS: - NormalizedLandmarkList +// Transformed face landmarks. +// +// Example: +// node { +// calculator: +// "mediapipe.tasks.vision.face_landmarker.TensorsToFaceLandmarksGraph" +// input_stream: "TENSORS:tensors" +// output_stream: "NORM_LANDMARKS:norm_landmarks" +// options { +// [mediapipe.tasks.vision.face_landmarker.proto.TensorsToFaceLandmarksGraphOptions.ext] +// { +// input_image_width: 192 +// input_image_height: 192 +// } +// } +// } +class TensorsToFaceLandmarksGraph : public Subgraph { + public: + absl::StatusOr GetConfig( + SubgraphContext* sc) override { + Graph graph; + auto norm_landmarks = BuildTensorsToFaceLandmarksGraph( + sc->Options(), + graph.In(kTensorsTag).Cast>(), graph); + norm_landmarks >> + graph.Out(kNormLandmarksTag).Cast(); + return graph.GetConfig(); + } + + private: + Stream BuildTensorsToFaceLandmarksGraph( + const proto::TensorsToFaceLandmarksGraphOptions& subgraph_options, + Stream> tensors, Graph& graph) { + const int input_image_width = subgraph_options.input_image_width(); + const int input_image_height = subgraph_options.input_image_height(); + if (subgraph_options.is_attention_model()) { + // Split tensors from attention model to 6 streams: mesh, lips, left_eye, + // right_eye, left_iris and right iris. + auto& split_tensors_vector = graph.AddNode("SplitTensorVectorCalculator"); + ConfigureSplitTensorVectorCalculator( + &split_tensors_vector + .GetOptions()); + tensors >> split_tensors_vector.In(""); + + auto mesh_landmarks = ConvertTensorsToLandmarks( + kMeshLandmarksNum, input_image_width, input_image_height, + split_tensors_vector.Out(0).Cast>(), graph); + auto lips_landmarks = ConvertTensorsToLandmarks( + kLipsLandmarksNum, input_image_width, input_image_height, + split_tensors_vector.Out(1).Cast>(), graph); + auto left_eye_landmarks = ConvertTensorsToLandmarks( + kEyeLandmarksNum, input_image_width, input_image_height, + split_tensors_vector.Out(2).Cast>(), graph); + auto right_eye_landmarks = ConvertTensorsToLandmarks( + kEyeLandmarksNum, input_image_width, input_image_height, + split_tensors_vector.Out(3).Cast>(), graph); + auto left_iris_landmarks = ConvertTensorsToLandmarks( + kIrisLandmarksNum, input_image_width, input_image_height, + split_tensors_vector.Out(4).Cast>(), graph); + auto right_iris_landmarks = ConvertTensorsToLandmarks( + kIrisLandmarksNum, input_image_width, input_image_height, + split_tensors_vector.Out(5).Cast>(), graph); + return RefineFaceLandmarks(mesh_landmarks, lips_landmarks, + left_eye_landmarks, right_eye_landmarks, + left_iris_landmarks, right_iris_landmarks, + graph); + } else { + return ConvertTensorsToLandmarks(kMeshLandmarksNum, input_image_width, + input_image_height, tensors, graph); + } + } +}; + +// clang-format off +REGISTER_MEDIAPIPE_GRAPH( + ::mediapipe::tasks::vision::face_landmarker::TensorsToFaceLandmarksGraph); // NOLINT +// clang-format on + +} // namespace face_landmarker +} // namespace vision +} // namespace tasks +} // namespace mediapipe diff --git a/mediapipe/tasks/testdata/vision/BUILD b/mediapipe/tasks/testdata/vision/BUILD index 9a222fff9..3e25370e7 100644 --- a/mediapipe/tasks/testdata/vision/BUILD +++ b/mediapipe/tasks/testdata/vision/BUILD @@ -41,6 +41,7 @@ mediapipe_files(srcs = [ "face_detection_full_range_sparse.tflite", "face_detection_short_range.tflite", "face_landmark.tflite", + "face_landmark_with_attention.tflite", "fist.jpg", "fist.png", "hand_landmark_full.tflite", @@ -140,6 +141,7 @@ filegroup( "face_detection_full_range_sparse.tflite", "face_detection_short_range.tflite", "face_landmark.tflite", + "face_landmark_with_attention.tflite", "hand_landmark_full.tflite", "hand_landmark_lite.tflite", "hand_landmarker.task", @@ -175,6 +177,7 @@ filegroup( "pointing_up_rotated_landmarks.pbtxt", "portrait_expected_detection.pbtxt", "portrait_expected_face_landmarks.pbtxt", + "portrait_expected_face_landmarks_with_attention.pbtxt", "thumb_up_landmarks.pbtxt", "thumb_up_rotated_landmarks.pbtxt", "victory_landmarks.pbtxt", diff --git a/mediapipe/tasks/testdata/vision/portrait_expected_face_landmarks_with_attention.pbtxt b/mediapipe/tasks/testdata/vision/portrait_expected_face_landmarks_with_attention.pbtxt new file mode 100644 index 000000000..2c8967bd4 --- /dev/null +++ b/mediapipe/tasks/testdata/vision/portrait_expected_face_landmarks_with_attention.pbtxt @@ -0,0 +1,1914 @@ +# proto-file: mediapipe/framework/formats/landmark.proto +# proto-message: NormalizedLandmarkList +landmark { + x: 0.49662378430366516 + y: 0.25066471099853516 +} +landmark { + x: 0.49648889899253845 + y: 0.22542163729667664 +} +landmark { + x: 0.4958636164665222 + y: 0.23273630440235138 +} +landmark { + x: 0.487348347902298 + y: 0.19578002393245697 +} +landmark { + x: 0.49650701880455017 + y: 0.2160423994064331 +} +landmark { + x: 0.4963602125644684 + y: 0.20415978133678436 +} +landmark { + x: 0.4958672821521759 + y: 0.1760016828775406 +} +landmark { + x: 0.4263756573200226 + y: 0.1743389070034027 +} +landmark { + x: 0.4957432150840759 + y: 0.15887980163097382 +} +landmark { + x: 0.49582991003990173 + y: 0.14792537689208984 +} +landmark { + x: 0.49545449018478394 + y: 0.10050265491008759 +} +landmark { + x: 0.4967471957206726 + y: 0.25292080640792847 +} +landmark { + x: 0.49677377939224243 + y: 0.25491753220558167 +} +landmark { + x: 0.4968340992927551 + y: 0.25597265362739563 +} +landmark { + x: 0.4966096580028534 + y: 0.2762660086154938 +} +landmark { + x: 0.4970662295818329 + y: 0.2792523503303528 +} +landmark { + x: 0.49733766913414 + y: 0.2831544280052185 +} +landmark { + x: 0.4975529909133911 + y: 0.28777939081192017 +} +landmark { + x: 0.49513718485832214 + y: 0.30162155628204346 +} +landmark { + x: 0.4963628351688385 + y: 0.23023517429828644 +} +landmark { + x: 0.48452815413475037 + y: 0.22930648922920227 +} +landmark { + x: 0.37912482023239136 + y: 0.14393068850040436 +} +landmark { + x: 0.45384323596954346 + y: 0.17952775955200195 +} +landmark { + x: 0.44406363368034363 + y: 0.18024367094039917 +} +landmark { + x: 0.43423992395401 + y: 0.18035075068473816 +} +landmark { + x: 0.42096418142318726 + y: 0.1774648129940033 +} +landmark { + x: 0.4620691239833832 + y: 0.17808954417705536 +} +landmark { + x: 0.4381572902202606 + y: 0.16171878576278687 +} +landmark { + x: 0.44929927587509155 + y: 0.16189174354076385 +} +landmark { + x: 0.42799487709999084 + y: 0.16344769299030304 +} +landmark { + x: 0.4213537871837616 + y: 0.16641879081726074 +} +landmark { + x: 0.4108949899673462 + y: 0.18241165578365326 +} +landmark { + x: 0.45295459032058716 + y: 0.3115408420562744 +} +landmark { + x: 0.42228829860687256 + y: 0.1732511818408966 +} +landmark { + x: 0.37566322088241577 + y: 0.1816394031047821 +} +landmark { + x: 0.39784568548202515 + y: 0.17866098880767822 +} +landmark { + x: 0.43882179260253906 + y: 0.21443405747413635 +} +landmark { + x: 0.4774819612503052 + y: 0.24866220355033875 +} +landmark { + x: 0.47887977957725525 + y: 0.25409185886383057 +} +landmark { + x: 0.45999351143836975 + y: 0.2500782310962677 +} +landmark { + x: 0.4481550455093384 + y: 0.252032995223999 +} +landmark { + x: 0.46404537558555603 + y: 0.25381025671958923 +} +landmark { + x: 0.4528164863586426 + y: 0.2544485628604889 +} +landmark { + x: 0.43636560440063477 + y: 0.27052366733551025 +} +landmark { + x: 0.4871026575565338 + y: 0.225237175822258 +} +landmark { + x: 0.48611801862716675 + y: 0.21604084968566895 +} +landmark { + x: 0.4063660502433777 + y: 0.1625554859638214 +} +landmark { + x: 0.4635976254940033 + y: 0.1942015290260315 +} +landmark { + x: 0.4581945836544037 + y: 0.21956732869148254 +} +landmark { + x: 0.4577708840370178 + y: 0.21461132168769836 +} +landmark { + x: 0.4065546691417694 + y: 0.21230843663215637 +} +landmark { + x: 0.48670515418052673 + y: 0.2050575613975525 +} +landmark { + x: 0.4322924315929413 + y: 0.15380477905273438 +} +landmark { + x: 0.4173465371131897 + y: 0.15705204010009766 +} +landmark { + x: 0.3902948796749115 + y: 0.1280173361301422 +} +landmark { + x: 0.4765879511833191 + y: 0.15888181328773499 +} +landmark { + x: 0.45905187726020813 + y: 0.16421911120414734 +} +landmark { + x: 0.4274546504020691 + y: 0.2575083076953888 +} +landmark { + x: 0.38783153891563416 + y: 0.2666078507900238 +} +landmark { + x: 0.46594077348709106 + y: 0.22510138154029846 +} +landmark { + x: 0.4754405915737152 + y: 0.2280336320400238 +} +landmark { + x: 0.4334415793418884 + y: 0.2578507959842682 +} +landmark { + x: 0.436551034450531 + y: 0.25822576880455017 +} +landmark { + x: 0.4111592769622803 + y: 0.1524781882762909 +} +landmark { + x: 0.45654183626174927 + y: 0.22234851121902466 +} +landmark { + x: 0.4520558714866638 + y: 0.15389353036880493 +} +landmark { + x: 0.44988009333610535 + y: 0.14750143885612488 +} +landmark { + x: 0.43465882539749146 + y: 0.10574661940336227 +} +landmark { + x: 0.3998187184333801 + y: 0.13816964626312256 +} +landmark { + x: 0.44287118315696716 + y: 0.12405438721179962 +} +landmark { + x: 0.3991505205631256 + y: 0.15909640491008759 +} +landmark { + x: 0.38786911964416504 + y: 0.15060681104660034 +} +landmark { + x: 0.4778904318809509 + y: 0.25174596905708313 +} +landmark { + x: 0.46195170283317566 + y: 0.2520931363105774 +} +landmark { + x: 0.45044994354248047 + y: 0.2533124089241028 +} +landmark { + x: 0.4682377278804779 + y: 0.22637511789798737 +} +landmark { + x: 0.4350201189517975 + y: 0.2580338418483734 +} +landmark { + x: 0.4423924684524536 + y: 0.2662544250488281 +} +landmark { + x: 0.43794137239456177 + y: 0.2584308385848999 +} +landmark { + x: 0.4733739197254181 + y: 0.22433938086032867 +} +landmark { + x: 0.4550367593765259 + y: 0.2551838159561157 +} +landmark { + x: 0.46616387367248535 + y: 0.25481677055358887 +} +landmark { + x: 0.48008614778518677 + y: 0.2553037405014038 +} +landmark { + x: 0.4764786660671234 + y: 0.3000088930130005 +} +landmark { + x: 0.47889888286590576 + y: 0.2867310047149658 +} +landmark { + x: 0.4792180061340332 + y: 0.28215786814689636 +} +landmark { + x: 0.4797844886779785 + y: 0.27831950783729553 +} +landmark { + x: 0.48065802454948425 + y: 0.27555787563323975 +} +landmark { + x: 0.4559228718280792 + y: 0.26986679434776306 +} +landmark { + x: 0.45390307903289795 + y: 0.2708792984485626 +} +landmark { + x: 0.4513547420501709 + y: 0.2728833556175232 +} +landmark { + x: 0.4496460258960724 + y: 0.27533650398254395 +} +landmark { + x: 0.4409347474575043 + y: 0.2433733493089676 +} +landmark { + x: 0.37470322847366333 + y: 0.2220018357038498 +} +landmark { + x: 0.49612095952033997 + y: 0.23190505802631378 +} +landmark { + x: 0.44766467809677124 + y: 0.2656818926334381 +} +landmark { + x: 0.4449608325958252 + y: 0.2656901478767395 +} +landmark { + x: 0.47903069853782654 + y: 0.23131167888641357 +} +landmark { + x: 0.45948758721351624 + y: 0.22670653462409973 +} +landmark { + x: 0.4773414433002472 + y: 0.22975307703018188 +} +landmark { + x: 0.4515821933746338 + y: 0.19823692739009857 +} +landmark { + x: 0.43330681324005127 + y: 0.20288488268852234 +} +landmark { + x: 0.4548875689506531 + y: 0.21785812079906464 +} +landmark { + x: 0.4081736207008362 + y: 0.11487754434347153 +} +landmark { + x: 0.41755422949790955 + y: 0.12904098629951477 +} +landmark { + x: 0.4283616244792938 + y: 0.14776825904846191 +} +landmark { + x: 0.4462631046772003 + y: 0.28206732869148254 +} +landmark { + x: 0.4730672240257263 + y: 0.14861562848091125 +} +landmark { + x: 0.4676840007305145 + y: 0.12226873636245728 +} +landmark { + x: 0.4625813066959381 + y: 0.10131789743900299 +} +landmark { + x: 0.42591845989227295 + y: 0.17952558398246765 +} +landmark { + x: 0.39877602458000183 + y: 0.18789303302764893 +} +landmark { + x: 0.467370867729187 + y: 0.17659270763397217 +} +landmark { + x: 0.41039395332336426 + y: 0.170170396566391 +} +landmark { + x: 0.4717400372028351 + y: 0.18922601640224457 +} +landmark { + x: 0.4667041003704071 + y: 0.21796613931655884 +} +landmark { + x: 0.3843420147895813 + y: 0.195051908493042 +} +landmark { + x: 0.40679413080215454 + y: 0.19237273931503296 +} +landmark { + x: 0.42057645320892334 + y: 0.19457939267158508 +} +landmark { + x: 0.4405983090400696 + y: 0.19333598017692566 +} +landmark { + x: 0.45518380403518677 + y: 0.19030749797821045 +} +landmark { + x: 0.46578195691108704 + y: 0.18687105178833008 +} +landmark { + x: 0.4859747886657715 + y: 0.178244948387146 +} +landmark { + x: 0.38405489921569824 + y: 0.2115805447101593 +} +landmark { + x: 0.40115848183631897 + y: 0.16971616446971893 +} +landmark { + x: 0.4904470443725586 + y: 0.22989952564239502 +} +landmark { + x: 0.4628409743309021 + y: 0.20227496325969696 +} +landmark { + x: 0.3713923692703247 + y: 0.18183395266532898 +} +landmark { + x: 0.4737045168876648 + y: 0.18296673893928528 +} +landmark { + x: 0.45343708992004395 + y: 0.217837393283844 +} +landmark { + x: 0.41712236404418945 + y: 0.17397862672805786 +} +landmark { + x: 0.46640586853027344 + y: 0.21179847419261932 +} +landmark { + x: 0.3793344795703888 + y: 0.24359717965126038 +} +landmark { + x: 0.4667336344718933 + y: 0.17424505949020386 +} +landmark { + x: 0.4768681228160858 + y: 0.20779715478420258 +} +landmark { + x: 0.409467488527298 + y: 0.28563350439071655 +} +landmark { + x: 0.41173893213272095 + y: 0.2989254593849182 +} +landmark { + x: 0.37547457218170166 + y: 0.2178495228290558 +} +landmark { + x: 0.3962154686450958 + y: 0.2734628915786743 +} +landmark { + x: 0.3811984956264496 + y: 0.16468137502670288 +} +landmark { + x: 0.4519205391407013 + y: 0.32255393266677856 +} +landmark { + x: 0.49128058552742004 + y: 0.2315189242362976 +} +landmark { + x: 0.45209217071533203 + y: 0.20766283571720123 +} +landmark { + x: 0.3879472613334656 + y: 0.18026039004325867 +} +landmark { + x: 0.43616294860839844 + y: 0.17546914517879486 +} +landmark { + x: 0.44427722692489624 + y: 0.1755416989326477 +} +landmark { + x: 0.44037607312202454 + y: 0.2670835852622986 +} +landmark { + x: 0.3844276964664459 + y: 0.23011347651481628 +} +landmark { + x: 0.47184261679649353 + y: 0.3377809524536133 +} +landmark { + x: 0.43982183933258057 + y: 0.3224796652793884 +} +landmark { + x: 0.42685991525650024 + y: 0.31230732798576355 +} +landmark { + x: 0.4956350028514862 + y: 0.12251447141170502 +} +landmark { + x: 0.4949685037136078 + y: 0.33993446826934814 +} +landmark { + x: 0.45213454961776733 + y: 0.17507293820381165 +} +landmark { + x: 0.4596617817878723 + y: 0.17446552217006683 +} +landmark { + x: 0.4645062983036041 + y: 0.1744132936000824 +} +landmark { + x: 0.39248085021972656 + y: 0.16815300285816193 +} +landmark { + x: 0.45720967650413513 + y: 0.1696319878101349 +} +landmark { + x: 0.44864439964294434 + y: 0.1680142879486084 +} +landmark { + x: 0.44060665369033813 + y: 0.1679076999425888 +} +landmark { + x: 0.4326114356517792 + y: 0.1691804826259613 +} +landmark { + x: 0.42759329080581665 + y: 0.1709102988243103 +} +landmark { + x: 0.37336626648902893 + y: 0.16072668135166168 +} +landmark { + x: 0.4305437207221985 + y: 0.17496828734874725 +} +landmark { + x: 0.49581199884414673 + y: 0.2378993183374405 +} +landmark { + x: 0.4533678889274597 + y: 0.23889966309070587 +} +landmark { + x: 0.46646663546562195 + y: 0.2243112325668335 +} +landmark { + x: 0.47728025913238525 + y: 0.23756998777389526 +} +landmark { + x: 0.49568256735801697 + y: 0.1670406311750412 +} +landmark { + x: 0.423678994178772 + y: 0.29920822381973267 +} +landmark { + x: 0.4373316168785095 + y: 0.31077975034713745 +} +landmark { + x: 0.4715747535228729 + y: 0.33032771944999695 +} +landmark { + x: 0.39951860904693604 + y: 0.2851996123790741 +} +landmark { + x: 0.46363309025764465 + y: 0.17234012484550476 +} +landmark { + x: 0.4789753258228302 + y: 0.19182273745536804 +} +landmark { + x: 0.4952210485935211 + y: 0.3327086865901947 +} +landmark { + x: 0.454120934009552 + y: 0.33151447772979736 +} +landmark { + x: 0.37874123454093933 + y: 0.23793040215969086 +} +landmark { + x: 0.4671173393726349 + y: 0.2732347548007965 +} +landmark { + x: 0.46523454785346985 + y: 0.2752726972103119 +} +landmark { + x: 0.4636782705783844 + y: 0.2785157561302185 +} +landmark { + x: 0.4628322422504425 + y: 0.2826366424560547 +} +landmark { + x: 0.45889154076576233 + y: 0.29270175099372864 +} +landmark { + x: 0.44332754611968994 + y: 0.2559441328048706 +} +landmark { + x: 0.4410799741744995 + y: 0.2552872896194458 +} +landmark { + x: 0.4392359256744385 + y: 0.2545016407966614 +} +landmark { + x: 0.4313274025917053 + y: 0.24908222258090973 +} +landmark { + x: 0.3969060182571411 + y: 0.23314312100410461 +} +landmark { + x: 0.47924545407295227 + y: 0.18325799703598022 +} +landmark { + x: 0.47463276982307434 + y: 0.1687009632587433 +} +landmark { + x: 0.4678848683834076 + y: 0.16957470774650574 +} +landmark { + x: 0.4455469250679016 + y: 0.2563154995441437 +} +landmark { + x: 0.39680883288383484 + y: 0.25723445415496826 +} +landmark { + x: 0.4837980568408966 + y: 0.1687287539243698 +} +landmark { + x: 0.4560215473175049 + y: 0.3008677363395691 +} +landmark { + x: 0.4962090253829956 + y: 0.19450967013835907 +} +landmark { + x: 0.48670148849487305 + y: 0.18738791346549988 +} +landmark { + x: 0.4960493743419647 + y: 0.18556331098079681 +} +landmark { + x: 0.47000551223754883 + y: 0.20461101830005646 +} +landmark { + x: 0.49529385566711426 + y: 0.32238951325416565 +} +landmark { + x: 0.49524635076522827 + y: 0.31086331605911255 +} +landmark { + x: 0.47470414638519287 + y: 0.30902671813964844 +} +landmark { + x: 0.43139365315437317 + y: 0.275373637676239 +} +landmark { + x: 0.44470104575157166 + y: 0.22494974732398987 +} +landmark { + x: 0.44245320558547974 + y: 0.2893069386482239 +} +landmark { + x: 0.4205935597419739 + y: 0.22470718622207642 +} +landmark { + x: 0.43413853645324707 + y: 0.2340032011270523 +} +landmark { + x: 0.41114354133605957 + y: 0.23891311883926392 +} +landmark { + x: 0.4724236726760864 + y: 0.32018566131591797 +} +landmark { + x: 0.4620009660720825 + y: 0.2084873765707016 +} +landmark { + x: 0.42516615986824036 + y: 0.28558987379074097 +} +landmark { + x: 0.43897202610969543 + y: 0.29905030131340027 +} +landmark { + x: 0.4220097064971924 + y: 0.26096412539482117 +} +landmark { + x: 0.3872614800930023 + y: 0.24655131995677948 +} +landmark { + x: 0.410627543926239 + y: 0.2659621238708496 +} +landmark { + x: 0.3853282928466797 + y: 0.25679436326026917 +} +landmark { + x: 0.4242616593837738 + y: 0.24355825781822205 +} +landmark { + x: 0.47135859727859497 + y: 0.19712591171264648 +} +landmark { + x: 0.4700557291507721 + y: 0.22256942093372345 +} +landmark { + x: 0.46150636672973633 + y: 0.22298608720302582 +} +landmark { + x: 0.47614237666130066 + y: 0.21702617406845093 +} +landmark { + x: 0.46710026264190674 + y: 0.16308291256427765 +} +landmark { + x: 0.4506882429122925 + y: 0.15922048687934875 +} +landmark { + x: 0.4361620247364044 + y: 0.15884718298912048 +} +landmark { + x: 0.4237998127937317 + y: 0.16090089082717896 +} +landmark { + x: 0.415077805519104 + y: 0.16471539437770844 +} +landmark { + x: 0.4087429642677307 + y: 0.1763523370027542 +} +landmark { + x: 0.374381959438324 + y: 0.19950927793979645 +} +landmark { + x: 0.41734278202056885 + y: 0.18508775532245636 +} +landmark { + x: 0.42812418937683105 + y: 0.18668216466903687 +} +landmark { + x: 0.44202420115470886 + y: 0.1863778680562973 +} +landmark { + x: 0.45476457476615906 + y: 0.18458959460258484 +} +landmark { + x: 0.46446532011032104 + y: 0.1823105812072754 +} +landmark { + x: 0.4710821509361267 + y: 0.1800185889005661 +} +landmark { + x: 0.3725321590900421 + y: 0.2018558830022812 +} +landmark { + x: 0.46095943450927734 + y: 0.22441256046295166 +} +landmark { + x: 0.4787464439868927 + y: 0.19961200654506683 +} +landmark { + x: 0.4787924885749817 + y: 0.22393538057804108 +} +landmark { + x: 0.4842645227909088 + y: 0.22833198308944702 +} +landmark { + x: 0.478278249502182 + y: 0.22533836960792542 +} +landmark { + x: 0.46331512928009033 + y: 0.22648602724075317 +} +landmark { + x: 0.4867161512374878 + y: 0.22926642000675201 +} +landmark { + x: 0.4873657822608948 + y: 0.23077093064785004 +} +landmark { + x: 0.47049492597579956 + y: 0.17447429895401 +} +landmark { + x: 0.47606557607650757 + y: 0.17599420249462128 +} +landmark { + x: 0.4794873595237732 + y: 0.17726632952690125 +} +landmark { + x: 0.42465925216674805 + y: 0.17222295701503754 +} +landmark { + x: 0.41689780354499817 + y: 0.1698952466249466 +} +landmark { + x: 0.5050461888313293 + y: 0.19569233059883118 +} +landmark { + x: 0.5678645968437195 + y: 0.17320770025253296 +} +landmark { + x: 0.507583737373352 + y: 0.22922341525554657 +} +landmark { + x: 0.6046732664108276 + y: 0.14386704564094543 +} +landmark { + x: 0.5400645136833191 + y: 0.17841511964797974 +} +landmark { + x: 0.5502756237983704 + y: 0.17885950207710266 +} +landmark { + x: 0.5601589679718018 + y: 0.1790323406457901 +} +landmark { + x: 0.5725513696670532 + y: 0.1765793412923813 +} +landmark { + x: 0.531100332736969 + y: 0.1772753894329071 +} +landmark { + x: 0.5557615160942078 + y: 0.1603943109512329 +} +landmark { + x: 0.5435649156570435 + y: 0.16075369715690613 +} +landmark { + x: 0.5666152834892273 + y: 0.16203095018863678 +} +landmark { + x: 0.5733098387718201 + y: 0.16506671905517578 +} +landmark { + x: 0.5821269154548645 + y: 0.18151146173477173 +} +landmark { + x: 0.537260115146637 + y: 0.31094133853912354 +} +landmark { + x: 0.5715002417564392 + y: 0.1723124235868454 +} +landmark { + x: 0.6100214719772339 + y: 0.1815027892589569 +} +landmark { + x: 0.5931045413017273 + y: 0.1776117980480194 +} +landmark { + x: 0.5521938800811768 + y: 0.21418961882591248 +} +landmark { + x: 0.5150473117828369 + y: 0.2477489411830902 +} +landmark { + x: 0.513859748840332 + y: 0.2532585561275482 +} +landmark { + x: 0.5315172076225281 + y: 0.2481025904417038 +} +landmark { + x: 0.5420610308647156 + y: 0.2493458092212677 +} +landmark { + x: 0.5276293754577637 + y: 0.25211772322654724 +} +landmark { + x: 0.5375497341156006 + y: 0.25211989879608154 +} +landmark { + x: 0.553263247013092 + y: 0.2699008882045746 +} +landmark { + x: 0.5057799816131592 + y: 0.22512458264827728 +} +landmark { + x: 0.5067881345748901 + y: 0.2159440815448761 +} +landmark { + x: 0.5869621634483337 + y: 0.1608346402645111 +} +landmark { + x: 0.5274977684020996 + y: 0.19401051104068756 +} +landmark { + x: 0.533601701259613 + y: 0.21943116188049316 +} +landmark { + x: 0.5338393449783325 + y: 0.21448351442813873 +} +landmark { + x: 0.583916962146759 + y: 0.21192994713783264 +} +landmark { + x: 0.5059342384338379 + y: 0.20495785772800446 +} +landmark { + x: 0.5629805326461792 + y: 0.15236346423625946 +} +landmark { + x: 0.5773332118988037 + y: 0.15538105368614197 +} +landmark { + x: 0.5952070951461792 + y: 0.12806709110736847 +} +landmark { + x: 0.5171068906784058 + y: 0.15756016969680786 +} +landmark { + x: 0.5328800678253174 + y: 0.16338685154914856 +} +landmark { + x: 0.5622146129608154 + y: 0.25687068700790405 +} +landmark { + x: 0.5980644822120667 + y: 0.26567089557647705 +} +landmark { + x: 0.5258244276046753 + y: 0.22496844828128815 +} +landmark { + x: 0.5163113474845886 + y: 0.22808413207530975 +} +landmark { + x: 0.5544278621673584 + y: 0.25414904952049255 +} +landmark { + x: 0.5511380434036255 + y: 0.25471070408821106 +} +landmark { + x: 0.582155704498291 + y: 0.15090274810791016 +} +landmark { + x: 0.5349514484405518 + y: 0.22227640450000763 +} +landmark { + x: 0.5432629585266113 + y: 0.15254999697208405 +} +landmark { + x: 0.545166552066803 + y: 0.14633391797542572 +} +landmark { + x: 0.5550372004508972 + y: 0.10590049624443054 +} +landmark { + x: 0.5876381397247314 + y: 0.13795891404151917 +} +landmark { + x: 0.547664225101471 + y: 0.12406198680400848 +} +landmark { + x: 0.5921664237976074 + y: 0.15760593116283417 +} +landmark { + x: 0.598299503326416 + y: 0.15034040808677673 +} +landmark { + x: 0.5147510766983032 + y: 0.2508791983127594 +} +landmark { + x: 0.5296086072921753 + y: 0.25031471252441406 +} +landmark { + x: 0.5399247407913208 + y: 0.2507742643356323 +} +landmark { + x: 0.5234197974205017 + y: 0.22629721462726593 +} +landmark { + x: 0.5528212785720825 + y: 0.2544132173061371 +} +landmark { + x: 0.5467516779899597 + y: 0.26323452591896057 +} +landmark { + x: 0.549625813961029 + y: 0.2550387680530548 +} +landmark { + x: 0.5189055800437927 + y: 0.22416916489601135 +} +landmark { + x: 0.5354100465774536 + y: 0.25290533900260925 +} +landmark { + x: 0.5255399346351624 + y: 0.25320950150489807 +} +landmark { + x: 0.5127152800559998 + y: 0.25454193353652954 +} +landmark { + x: 0.5138126611709595 + y: 0.299878865480423 +} +landmark { + x: 0.515352725982666 + y: 0.28621500730514526 +} +landmark { + x: 0.5145734548568726 + y: 0.28150495886802673 +} +landmark { + x: 0.513367235660553 + y: 0.2775838077068329 +} +landmark { + x: 0.5117818713188171 + y: 0.2747820317745209 +} +landmark { + x: 0.5339730978012085 + y: 0.26765158772468567 +} +landmark { + x: 0.5364535450935364 + y: 0.26869869232177734 +} +landmark { + x: 0.5393399000167847 + y: 0.2706717848777771 +} +landmark { + x: 0.54141765832901 + y: 0.2732411026954651 +} +landmark { + x: 0.549669086933136 + y: 0.24306340515613556 +} +landmark { + x: 0.6092031002044678 + y: 0.2215307354927063 +} +landmark { + x: 0.5411204099655151 + y: 0.26294228434562683 +} +landmark { + x: 0.5440355539321899 + y: 0.2628013491630554 +} +landmark { + x: 0.5127156972885132 + y: 0.23138798773288727 +} +landmark { + x: 0.531876802444458 + y: 0.22674860060214996 +} +landmark { + x: 0.5144256949424744 + y: 0.22982563078403473 +} +landmark { + x: 0.5392422676086426 + y: 0.19801364839076996 +} +landmark { + x: 0.5575653314590454 + y: 0.20261937379837036 +} +landmark { + x: 0.5365014672279358 + y: 0.21780844032764435 +} +landmark { + x: 0.5796245336532593 + y: 0.11501635611057281 +} +landmark { + x: 0.5714046955108643 + y: 0.1289663314819336 +} +landmark { + x: 0.566118597984314 + y: 0.14649400115013123 +} +landmark { + x: 0.5435302257537842 + y: 0.2815547585487366 +} +landmark { + x: 0.5208231806755066 + y: 0.14749842882156372 +} +landmark { + x: 0.5235199928283691 + y: 0.12231816351413727 +} +landmark { + x: 0.5280724763870239 + y: 0.10143059492111206 +} +landmark { + x: 0.5680530667304993 + y: 0.1783541738986969 +} +landmark { + x: 0.5935924053192139 + y: 0.18684668838977814 +} +landmark { + x: 0.5251346230506897 + y: 0.17590194940567017 +} +landmark { + x: 0.5829108953475952 + y: 0.16882555186748505 +} +landmark { + x: 0.5196100473403931 + y: 0.18905554711818695 +} +landmark { + x: 0.5255730152130127 + y: 0.21781699359416962 +} +landmark { + x: 0.6037929058074951 + y: 0.19473719596862793 +} +landmark { + x: 0.5876762866973877 + y: 0.19139209389686584 +} +landmark { + x: 0.5751091241836548 + y: 0.19363407790660858 +} +landmark { + x: 0.5546884536743164 + y: 0.19245529174804688 +} +landmark { + x: 0.5392851829528809 + y: 0.1895231455564499 +} +landmark { + x: 0.5278844833374023 + y: 0.18625354766845703 +} +landmark { + x: 0.5057379603385925 + y: 0.1781947761774063 +} +landmark { + x: 0.6048473119735718 + y: 0.21124869585037231 +} +landmark { + x: 0.5907138586044312 + y: 0.16841086745262146 +} +landmark { + x: 0.5022064447402954 + y: 0.22984524071216583 +} +landmark { + x: 0.5283474326133728 + y: 0.20210015773773193 +} +landmark { + x: 0.6115738749504089 + y: 0.18162932991981506 +} +landmark { + x: 0.5195339322090149 + y: 0.18231819570064545 +} +landmark { + x: 0.5375816822052002 + y: 0.21782614290714264 +} +landmark { + x: 0.5763388872146606 + y: 0.17313891649246216 +} +landmark { + x: 0.5256010890007019 + y: 0.21164333820343018 +} +landmark { + x: 0.6055155396461487 + y: 0.24294571578502655 +} +landmark { + x: 0.5247454643249512 + y: 0.17330946028232574 +} +landmark { + x: 0.5155066251754761 + y: 0.2076435387134552 +} +landmark { + x: 0.5793409943580627 + y: 0.2845692038536072 +} +landmark { + x: 0.5759055614471436 + y: 0.29750049114227295 +} +landmark { + x: 0.6111270785331726 + y: 0.2174876481294632 +} +landmark { + x: 0.5920206904411316 + y: 0.27248382568359375 +} +landmark { + x: 0.6044109463691711 + y: 0.16451576352119446 +} +landmark { + x: 0.5379455089569092 + y: 0.32187914848327637 +} +landmark { + x: 0.5009083151817322 + y: 0.23150548338890076 +} +landmark { + x: 0.5388193130493164 + y: 0.2075142115354538 +} +landmark { + x: 0.6010805368423462 + y: 0.17926880717277527 +} +landmark { + x: 0.5587165355682373 + y: 0.1739545315504074 +} +landmark { + x: 0.5504672527313232 + y: 0.1740606129169464 +} +landmark { + x: 0.5489862561225891 + y: 0.2640478312969208 +} +landmark { + x: 0.6047309637069702 + y: 0.22963711619377136 +} +landmark { + x: 0.5178425908088684 + y: 0.33742693066596985 +} +landmark { + x: 0.5490055084228516 + y: 0.32128745317459106 +} +landmark { + x: 0.5615330934524536 + y: 0.31093350052833557 +} +landmark { + x: 0.5419384241104126 + y: 0.17382308840751648 +} +landmark { + x: 0.5334516763687134 + y: 0.17353390157222748 +} +landmark { + x: 0.5276540517807007 + y: 0.17363135516643524 +} +landmark { + x: 0.5970168709754944 + y: 0.1669829785823822 +} +landmark { + x: 0.534781813621521 + y: 0.1685568243265152 +} +landmark { + x: 0.5438240766525269 + y: 0.16664481163024902 +} +landmark { + x: 0.5528751015663147 + y: 0.1663939356803894 +} +landmark { + x: 0.5614930391311646 + y: 0.1677042543888092 +} +landmark { + x: 0.5666491389274597 + y: 0.16964749991893768 +} +landmark { + x: 0.609628438949585 + y: 0.16061675548553467 +} +landmark { + x: 0.564093291759491 + y: 0.17360816895961761 +} +landmark { + x: 0.5377736687660217 + y: 0.23875702917575836 +} +landmark { + x: 0.5254501700401306 + y: 0.22414736449718475 +} +landmark { + x: 0.5143731236457825 + y: 0.23756679892539978 +} +landmark { + x: 0.5653495788574219 + y: 0.2981868386268616 +} +landmark { + x: 0.5520498752593994 + y: 0.3098434507846832 +} +landmark { + x: 0.5187731385231018 + y: 0.3300126791000366 +} +landmark { + x: 0.5873982310295105 + y: 0.2838709354400635 +} +landmark { + x: 0.5280466079711914 + y: 0.17138159275054932 +} +landmark { + x: 0.5129181146621704 + y: 0.19168895483016968 +} +landmark { + x: 0.5351779460906982 + y: 0.33067697286605835 +} +landmark { + x: 0.6082624197006226 + y: 0.2374051958322525 +} +landmark { + x: 0.5241615772247314 + y: 0.27171289920806885 +} +landmark { + x: 0.5266141891479492 + y: 0.27379295229911804 +} +landmark { + x: 0.5287306904792786 + y: 0.27710697054862976 +} +landmark { + x: 0.5302250385284424 + y: 0.2814483940601349 +} +landmark { + x: 0.5311165452003479 + y: 0.2923078238964081 +} +landmark { + x: 0.5454117655754089 + y: 0.25298070907592773 +} +landmark { + x: 0.5476760268211365 + y: 0.2521646320819855 +} +landmark { + x: 0.5496358871459961 + y: 0.2512545585632324 +} +landmark { + x: 0.5587289333343506 + y: 0.24860405921936035 +} +landmark { + x: 0.5932571291923523 + y: 0.2326328307390213 +} +landmark { + x: 0.5122402906417847 + y: 0.18319103121757507 +} +landmark { + x: 0.5172679424285889 + y: 0.16791534423828125 +} +landmark { + x: 0.5236363410949707 + y: 0.16878443956375122 +} +landmark { + x: 0.5432159900665283 + y: 0.2535431385040283 +} +landmark { + x: 0.5924032330513 + y: 0.2564423978328705 +} +landmark { + x: 0.5086346864700317 + y: 0.16782936453819275 +} +landmark { + x: 0.5341810584068298 + y: 0.3003450036048889 +} +landmark { + x: 0.5053712725639343 + y: 0.18729014694690704 +} +landmark { + x: 0.52167147397995 + y: 0.20450185239315033 +} +landmark { + x: 0.5157896280288696 + y: 0.30877235531806946 +} +landmark { + x: 0.5582626461982727 + y: 0.27466052770614624 +} +landmark { + x: 0.5460183620452881 + y: 0.22478628158569336 +} +landmark { + x: 0.5473951101303101 + y: 0.2886243462562561 +} +landmark { + x: 0.5703837871551514 + y: 0.22428280115127563 +} +landmark { + x: 0.5565193295478821 + y: 0.23365134000778198 +} +landmark { + x: 0.5793741345405579 + y: 0.23838575184345245 +} +landmark { + x: 0.5181536674499512 + y: 0.31991374492645264 +} +landmark { + x: 0.529270589351654 + y: 0.2083507925271988 +} +landmark { + x: 0.5643376111984253 + y: 0.28466808795928955 +} +landmark { + x: 0.5508216619491577 + y: 0.2982299327850342 +} +landmark { + x: 0.5677818059921265 + y: 0.2603156566619873 +} +landmark { + x: 0.6016684770584106 + y: 0.24588267505168915 +} +landmark { + x: 0.5789523720741272 + y: 0.2651319205760956 +} +landmark { + x: 0.602148175239563 + y: 0.2560369372367859 +} +landmark { + x: 0.56609046459198 + y: 0.24309805035591125 +} +landmark { + x: 0.5201491713523865 + y: 0.19698408246040344 +} +landmark { + x: 0.5222632884979248 + y: 0.22236193716526031 +} +landmark { + x: 0.5303317904472351 + y: 0.22283218801021576 +} +landmark { + x: 0.5164652466773987 + y: 0.2168644219636917 +} +landmark { + x: 0.5255054235458374 + y: 0.16204464435577393 +} +landmark { + x: 0.5431230068206787 + y: 0.15799033641815186 +} +landmark { + x: 0.5587068796157837 + y: 0.1575303077697754 +} +landmark { + x: 0.5712164640426636 + y: 0.15946003794670105 +} +landmark { + x: 0.5793605446815491 + y: 0.16321201622486115 +} +landmark { + x: 0.5836203098297119 + y: 0.17538323998451233 +} +landmark { + x: 0.6116812825202942 + y: 0.19925269484519958 +} +landmark { + x: 0.5768086910247803 + y: 0.1841469705104828 +} +landmark { + x: 0.5665790438652039 + y: 0.18563959002494812 +} +landmark { + x: 0.5525866746902466 + y: 0.18530991673469543 +} +landmark { + x: 0.5391771793365479 + y: 0.1836860328912735 +} +landmark { + x: 0.5287002325057983 + y: 0.18165405094623566 +} +landmark { + x: 0.5215262174606323 + y: 0.1793644279241562 +} +landmark { + x: 0.6107636094093323 + y: 0.20149710774421692 +} +landmark { + x: 0.5306032299995422 + y: 0.22430402040481567 +} +landmark { + x: 0.5133494138717651 + y: 0.19946259260177612 +} +landmark { + x: 0.5138635635375977 + y: 0.22376540303230286 +} +landmark { + x: 0.5081169009208679 + y: 0.22823618352413177 +} +landmark { + x: 0.5141233205795288 + y: 0.2252192348241806 +} +landmark { + x: 0.5282045006752014 + y: 0.22643950581550598 +} +landmark { + x: 0.5058442950248718 + y: 0.2291848063468933 +} +landmark { + x: 0.5046985745429993 + y: 0.23070128262043 +} +landmark { + x: 0.5212299823760986 + y: 0.17368891835212708 +} +landmark { + x: 0.5159528255462646 + y: 0.17531193792819977 +} +landmark { + x: 0.5131956338882446 + y: 0.17659029364585876 +} +landmark { + x: 0.5694946050643921 + y: 0.1711338460445404 +} +landmark { + x: 0.5771481990814209 + y: 0.1686939150094986 +} +landmark { + x: 0.44258421659469604 + y: 0.17109623551368713 +} +landmark { + x: 0.4528672397136688 + y: 0.17074066400527954 +} +landmark { + x: 0.44241371750831604 + y: 0.1644783616065979 +} +landmark { + x: 0.4321419894695282 + y: 0.17140239477157593 +} +landmark { + x: 0.44269701838493347 + y: 0.17766216397285461 +} +landmark { + x: 0.5497130155563354 + y: 0.1701773703098297 +} +landmark { + x: 0.5605489611625671 + y: 0.17030568420886993 +} +landmark { + x: 0.5500174760818481 + y: 0.1636604368686676 +} +landmark { + x: 0.538931667804718 + y: 0.17000019550323486 +} +landmark { + x: 0.5495142340660095 + y: 0.17672255635261536 +} diff --git a/third_party/external_files.bzl b/third_party/external_files.bzl index d3e0b41e6..7122c6771 100644 --- a/third_party/external_files.bzl +++ b/third_party/external_files.bzl @@ -724,6 +724,12 @@ def external_files(): urls = ["https://storage.googleapis.com/mediapipe-assets/portrait_expected_face_landmarks.pbtxt?generation=1676316357333369"], ) + http_file( + name = "com_google_mediapipe_portrait_expected_face_landmarks_with_attention_pbtxt", + sha256 = "f2ccd889654b914996e4aab0d7831a3e73d3b63d6c14f6bac4bec5cd3415bce4", + urls = ["https://storage.googleapis.com/mediapipe-assets/portrait_expected_face_landmarks_with_attention.pbtxt?generation=1676415475626542"], + ) + http_file( name = "com_google_mediapipe_portrait_jpg", sha256 = "a6f11efaa834706db23f275b6115058fa87fc7f14362681e6abe14e82749de3e",