diff --git a/mediapipe/tasks/cc/core/BUILD b/mediapipe/tasks/cc/core/BUILD index f3258a606..291dd29fe 100644 --- a/mediapipe/tasks/cc/core/BUILD +++ b/mediapipe/tasks/cc/core/BUILD @@ -73,6 +73,7 @@ cc_library( srcs = ["model_task_graph.cc"], hdrs = ["model_task_graph.h"], deps = [ + ":model_asset_bundle_resources", ":model_resources", ":model_resources_cache", ":model_resources_calculator", @@ -163,6 +164,7 @@ cc_library_with_tflite( "@org_tensorflow//tensorflow/lite/core/shims:builtin_ops", ], deps = [ + ":model_asset_bundle_resources", "//mediapipe/framework:calculator_framework", "//mediapipe/framework/api2:packet", "//mediapipe/tasks/cc:common", diff --git a/mediapipe/tasks/cc/core/model_resources_cache.cc b/mediapipe/tasks/cc/core/model_resources_cache.cc index 216962bcf..affcb6dea 100644 --- a/mediapipe/tasks/cc/core/model_resources_cache.cc +++ b/mediapipe/tasks/cc/core/model_resources_cache.cc @@ -26,6 +26,7 @@ limitations under the License. #include "absl/strings/substitute.h" #include "mediapipe/framework/api2/packet.h" #include "mediapipe/tasks/cc/common.h" +#include "mediapipe/tasks/cc/core/model_asset_bundle_resources.h" #include "mediapipe/tasks/cc/core/model_resources.h" #include "tensorflow/lite/core/api/op_resolver.h" @@ -39,12 +40,16 @@ ModelResourcesCache::ModelResourcesCache( graph_op_resolver_packet_ = api2::PacketAdopting(std::move(graph_op_resolver)); } -}; +} bool ModelResourcesCache::Exists(const std::string& tag) const { return model_resources_collection_.contains(tag); } +bool ModelResourcesCache::ModelAssetBundleExists(const std::string& tag) const { + return model_asset_bundle_resources_collection_.contains(tag); +} + absl::Status ModelResourcesCache::AddModelResources( std::unique_ptr model_resources) { if (model_resources == nullptr) { @@ -94,6 +99,62 @@ absl::StatusOr ModelResourcesCache::GetModelResources( return model_resources_collection_.at(tag).get(); } +absl::Status ModelResourcesCache::AddModelAssetBundleResources( + std::unique_ptr model_asset_bundle_resources) { + if (model_asset_bundle_resources == nullptr) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + "ModelAssetBundleResources object is null.", + MediaPipeTasksStatus::kRunnerModelResourcesCacheServiceError); + } + const std::string& tag = model_asset_bundle_resources->GetTag(); + if (tag.empty()) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + "ModelAssetBundleResources must have a non-empty tag.", + MediaPipeTasksStatus::kRunnerModelResourcesCacheServiceError); + } + if (ModelAssetBundleExists(tag)) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::Substitute( + "ModelAssetBundleResources with tag \"$0\" already exists.", tag), + MediaPipeTasksStatus::kRunnerModelResourcesCacheServiceError); + } + model_asset_bundle_resources_collection_.emplace( + tag, std::move(model_asset_bundle_resources)); + return absl::OkStatus(); +} + +absl::Status ModelResourcesCache::AddModelAssetBundleResourcesCollection( + std::vector>& + model_asset_bundle_resources_collection) { + for (auto& model_bundle_resources : model_asset_bundle_resources_collection) { + MP_RETURN_IF_ERROR( + AddModelAssetBundleResources(std::move(model_bundle_resources))); + } + return absl::OkStatus(); +} + +absl::StatusOr +ModelResourcesCache::GetModelAssetBundleResources( + const std::string& tag) const { + if (tag.empty()) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + "ModelAssetBundleResources must be retrieved with a non-empty tag.", + MediaPipeTasksStatus::kRunnerModelResourcesCacheServiceError); + } + if (!ModelAssetBundleExists(tag)) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::Substitute( + "ModelAssetBundleResources with tag \"$0\" does not exist.", tag), + MediaPipeTasksStatus::kRunnerModelResourcesCacheServiceError); + } + return model_asset_bundle_resources_collection_.at(tag).get(); +} + absl::StatusOr> ModelResourcesCache::GetGraphOpResolverPacket() const { if (graph_op_resolver_packet_.IsEmpty()) { diff --git a/mediapipe/tasks/cc/core/model_resources_cache.h b/mediapipe/tasks/cc/core/model_resources_cache.h index 044ef36b7..32909f93d 100644 --- a/mediapipe/tasks/cc/core/model_resources_cache.h +++ b/mediapipe/tasks/cc/core/model_resources_cache.h @@ -26,6 +26,7 @@ limitations under the License. #include "absl/status/statusor.h" #include "mediapipe/framework/api2/packet.h" #include "mediapipe/framework/calculator_framework.h" +#include "mediapipe/tasks/cc/core/model_asset_bundle_resources.h" #include "mediapipe/tasks/cc/core/model_resources.h" #include "tensorflow/lite/core/api/op_resolver.h" @@ -46,6 +47,10 @@ class ModelResourcesCache { // Returns whether the tag exists in the model resources cache. bool Exists(const std::string& tag) const; + // Returns whether the tag of the model asset bundle exists in the model + // resources cache. + bool ModelAssetBundleExists(const std::string& tag) const; + // Adds a ModelResources object into the cache. // The tag of the ModelResources must be unique; the ownership of the // ModelResources will be transferred into the cache. @@ -62,6 +67,23 @@ class ModelResourcesCache { absl::StatusOr GetModelResources( const std::string& tag) const; + // Adds a ModelAssetBundleResources object into the cache. + // The tag of the ModelAssetBundleResources must be unique; the ownership of + // the ModelAssetBundleResources will be transferred into the cache. + absl::Status AddModelAssetBundleResources( + std::unique_ptr model_asset_bundle_resources); + + // Adds a collection of the ModelAssetBundleResources objects into the cache. + // The tag of the each ModelAssetBundleResources must be unique; the ownership + // of every ModelAssetBundleResources will be transferred into the cache. + absl::Status AddModelAssetBundleResourcesCollection( + std::vector>& + model_asset_bundle_resources_collection); + + // Retrieves a const ModelAssetBundleResources pointer by the unique tag. + absl::StatusOr GetModelAssetBundleResources( + const std::string& tag) const; + // Retrieves the graph op resolver packet. absl::StatusOr> GetGraphOpResolverPacket() const; @@ -73,6 +95,11 @@ class ModelResourcesCache { // A collection of ModelResources objects for the models in the graph. absl::flat_hash_map> model_resources_collection_; + + // A collection of ModelAssetBundleResources objects for the model bundles in + // the graph. + absl::flat_hash_map> + model_asset_bundle_resources_collection_; }; // Global service for mediapipe task model resources cache. diff --git a/mediapipe/tasks/cc/core/model_task_graph.cc b/mediapipe/tasks/cc/core/model_task_graph.cc index 90a38747c..47334b673 100644 --- a/mediapipe/tasks/cc/core/model_task_graph.cc +++ b/mediapipe/tasks/cc/core/model_task_graph.cc @@ -32,6 +32,7 @@ limitations under the License. #include "mediapipe/framework/calculator.pb.h" #include "mediapipe/framework/port/logging.h" #include "mediapipe/tasks/cc/common.h" +#include "mediapipe/tasks/cc/core/model_asset_bundle_resources.h" #include "mediapipe/tasks/cc/core/model_resources.h" #include "mediapipe/tasks/cc/core/model_resources_cache.h" #include "mediapipe/tasks/cc/core/proto/acceleration.pb.h" @@ -70,6 +71,17 @@ std::string CreateModelResourcesTag(const CalculatorGraphConfig::Node& node) { node_type); } +std::string CreateModelAssetBundleResourcesTag( + const CalculatorGraphConfig::Node& node) { + std::vector names = absl::StrSplit(node.name(), "__"); + std::string node_type = node.calculator(); + std::replace(node_type.begin(), node_type.end(), '.', '_'); + absl::AsciiStrToLower(&node_type); + return absl::StrFormat("%s_%s_model_asset_bundle_resources", + names.back().empty() ? "unnamed" : names.back(), + node_type); +} + } // namespace // Defines the mediapipe task inference unit as a MediaPipe subgraph that @@ -168,6 +180,38 @@ absl::StatusOr ModelTaskGraph::CreateModelResources( return model_resources_cache_service.GetObject().GetModelResources(tag); } +absl::StatusOr +ModelTaskGraph::CreateModelAssetBundleResources( + SubgraphContext* sc, std::unique_ptr external_file) { + auto model_resources_cache_service = sc->Service(kModelResourcesCacheService); + bool has_file_pointer_meta = external_file->has_file_pointer_meta(); + // if external file is set by file pointer, no need to add the model asset + // bundle resources into the model resources service since the memory is + // not owned by this model asset bundle resources. + if (!model_resources_cache_service.IsAvailable() || has_file_pointer_meta) { + ASSIGN_OR_RETURN( + local_model_asset_bundle_resources_, + ModelAssetBundleResources::Create("", std::move(external_file))); + if (!has_file_pointer_meta) { + LOG(WARNING) + << "A local ModelResources object is created. Please consider using " + "ModelResourcesCacheService to cache the created ModelResources " + "object in the CalculatorGraph."; + } + return local_model_asset_bundle_resources_.get(); + } + const std::string tag = + CreateModelAssetBundleResourcesTag(sc->OriginalNode()); + ASSIGN_OR_RETURN( + auto model_bundle_resources, + ModelAssetBundleResources::Create(tag, std::move(external_file))); + MP_RETURN_IF_ERROR( + model_resources_cache_service.GetObject().AddModelAssetBundleResources( + std::move(model_bundle_resources))); + return model_resources_cache_service.GetObject().GetModelAssetBundleResources( + tag); +} + GenericNode& ModelTaskGraph::AddInference( const ModelResources& model_resources, const proto::Acceleration& acceleration, Graph& graph) const { diff --git a/mediapipe/tasks/cc/core/model_task_graph.h b/mediapipe/tasks/cc/core/model_task_graph.h index 36016cb89..5ee70e8f3 100644 --- a/mediapipe/tasks/cc/core/model_task_graph.h +++ b/mediapipe/tasks/cc/core/model_task_graph.h @@ -27,6 +27,7 @@ limitations under the License. #include "mediapipe/framework/calculator.pb.h" #include "mediapipe/framework/calculator_framework.h" #include "mediapipe/framework/subgraph.h" +#include "mediapipe/tasks/cc/core/model_asset_bundle_resources.h" #include "mediapipe/tasks/cc/core/model_resources.h" #include "mediapipe/tasks/cc/core/proto/acceleration.pb.h" #include "mediapipe/tasks/cc/core/proto/base_options.pb.h" @@ -78,6 +79,35 @@ class ModelTaskGraph : public Subgraph { absl::StatusOr CreateModelResources( SubgraphContext* sc, std::unique_ptr external_file); + // If the model resources graph service is available, creates a model asset + // bundle resources object from the subgraph context, and caches the created + // model asset bundle resources into the model resources graph service on + // success. Otherwise, creates a local model asset bundle resources object + // that can only be used in the graph construction stage. The returned model + // resources pointer will provide graph authors with the access to extracted + // model files. + template + absl::StatusOr + CreateModelAssetBundleResources(SubgraphContext* sc) { + auto external_file = std::make_unique(); + external_file->Swap(sc->MutableOptions() + ->mutable_base_options() + ->mutable_model_asset()); + return CreateModelAssetBundleResources(sc, std::move(external_file)); + } + + // If the model resources graph service is available, creates a model asset + // bundle resources object from the subgraph context, and caches the created + // model asset bundle resources into the model resources graph service on + // success. Otherwise, creates a local model asset bundle resources object + // that can only be used in the graph construction stage. Note that the + // external file contents will be moved into the model asset bundle resources + // object on creation. The returned model asset bundle resources pointer will + // provide graph authors with the access to extracted model files. + absl::StatusOr + CreateModelAssetBundleResources( + SubgraphContext* sc, std::unique_ptr external_file); + // Inserts a mediapipe task inference subgraph into the provided // GraphBuilder. The returned node provides the following interfaces to the // the rest of the graph: @@ -95,6 +125,9 @@ class ModelTaskGraph : public Subgraph { private: std::unique_ptr local_model_resources_; + + std::unique_ptr + local_model_asset_bundle_resources_; }; } // namespace core diff --git a/mediapipe/tasks/cc/metadata/utils/zip_utils.cc b/mediapipe/tasks/cc/metadata/utils/zip_utils.cc index 41d710e14..2c09e1961 100644 --- a/mediapipe/tasks/cc/metadata/utils/zip_utils.cc +++ b/mediapipe/tasks/cc/metadata/utils/zip_utils.cc @@ -15,6 +15,8 @@ limitations under the License. #include "mediapipe/tasks/cc/metadata/utils/zip_utils.h" +#include + #include "absl/cleanup/cleanup.h" #include "absl/container/flat_hash_map.h" #include "absl/status/status.h" @@ -162,12 +164,16 @@ absl::Status ExtractFilesfromZipFile( return absl::OkStatus(); } -void SetExternalFile(const std::string_view& file_content, - core::proto::ExternalFile* model_file) { - auto pointer = reinterpret_cast(file_content.data()); - - model_file->mutable_file_pointer_meta()->set_pointer(pointer); - model_file->mutable_file_pointer_meta()->set_length(file_content.length()); +void SetExternalFile(const absl::string_view& file_content, + core::proto::ExternalFile* model_file, bool is_copy) { + if (is_copy) { + std::string str_content{file_content}; + model_file->set_file_content(str_content); + } else { + auto pointer = reinterpret_cast(file_content.data()); + model_file->mutable_file_pointer_meta()->set_pointer(pointer); + model_file->mutable_file_pointer_meta()->set_length(file_content.length()); + } } } // namespace metadata diff --git a/mediapipe/tasks/cc/metadata/utils/zip_utils.h b/mediapipe/tasks/cc/metadata/utils/zip_utils.h index 28708ba6a..10ad0a5a9 100644 --- a/mediapipe/tasks/cc/metadata/utils/zip_utils.h +++ b/mediapipe/tasks/cc/metadata/utils/zip_utils.h @@ -35,10 +35,13 @@ absl::Status ExtractFilesfromZipFile( const char* buffer_data, const size_t buffer_size, absl::flat_hash_map* files); -// Set file_pointer_meta in ExternalFile which is the pointer points to location -// of a file in memory by file_content. -void SetExternalFile(const std::string_view& file_content, - core::proto::ExternalFile* model_file); +// Set the ExternalFile object by file_content in memory. By default, +// `is_copy=false` which means to set `file_pointer_meta` in ExternalFile which +// is the pointer points to location of a file in memory. Otherwise, if +// `is_copy=true`, copy the memory into `file_content` in ExternalFile. +void SetExternalFile(const absl::string_view& file_content, + core::proto::ExternalFile* model_file, + bool is_copy = false); } // namespace metadata } // namespace tasks diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/BUILD b/mediapipe/tasks/cc/vision/hand_landmarker/BUILD index e8a832bbc..9090fc7b3 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/BUILD +++ b/mediapipe/tasks/cc/vision/hand_landmarker/BUILD @@ -91,10 +91,14 @@ cc_library( "//mediapipe/framework/formats:landmark_cc_proto", "//mediapipe/framework/formats:rect_cc_proto", "//mediapipe/framework/formats:tensor", + "//mediapipe/framework/port:status", "//mediapipe/tasks/cc:common", "//mediapipe/tasks/cc/components/utils:gate", + "//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/core:utils", + "//mediapipe/tasks/cc/metadata/utils:zip_utils", "//mediapipe/tasks/cc/vision/hand_detector:hand_detector_graph", "//mediapipe/tasks/cc/vision/hand_detector/proto:hand_detector_graph_options_cc_proto", "//mediapipe/tasks/cc/vision/hand_landmarker/calculators:hand_association_calculator", diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph.cc index ab5a453c5..7e199348c 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph.cc @@ -29,10 +29,14 @@ limitations under the License. #include "mediapipe/framework/formats/landmark.pb.h" #include "mediapipe/framework/formats/rect.pb.h" #include "mediapipe/framework/formats/tensor.h" +#include "mediapipe/framework/port/status_macros.h" #include "mediapipe/tasks/cc/common.h" #include "mediapipe/tasks/cc/components/utils/gate.h" +#include "mediapipe/tasks/cc/core/model_asset_bundle_resources.h" +#include "mediapipe/tasks/cc/core/model_resources_cache.h" #include "mediapipe/tasks/cc/core/model_task_graph.h" #include "mediapipe/tasks/cc/core/utils.h" +#include "mediapipe/tasks/cc/metadata/utils/zip_utils.h" #include "mediapipe/tasks/cc/vision/hand_detector/proto/hand_detector_graph_options.pb.h" #include "mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator.pb.h" #include "mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarker_graph_options.pb.h" @@ -50,6 +54,8 @@ using ::mediapipe::api2::Output; using ::mediapipe::api2::builder::Graph; using ::mediapipe::api2::builder::Source; using ::mediapipe::tasks::components::utils::DisallowIf; +using ::mediapipe::tasks::core::ModelAssetBundleResources; +using ::mediapipe::tasks::metadata::SetExternalFile; using ::mediapipe::tasks::vision::hand_detector::proto:: HandDetectorGraphOptions; using ::mediapipe::tasks::vision::hand_landmarker::proto:: @@ -65,6 +71,9 @@ constexpr char kHandednessTag[] = "HANDEDNESS"; constexpr char kPalmDetectionsTag[] = "PALM_DETECTIONS"; constexpr char kPalmRectsTag[] = "PALM_RECTS"; constexpr char kPreviousLoopbackCalculatorName[] = "PreviousLoopbackCalculator"; +constexpr char kHandDetectorTFLiteName[] = "hand_detector.tflite"; +constexpr char kHandLandmarksDetectorTFLiteName[] = + "hand_landmarks_detector.tflite"; struct HandLandmarkerOutputs { Source> landmark_lists; @@ -76,6 +85,27 @@ struct HandLandmarkerOutputs { Source image; }; +// Sets the base options in the sub tasks. +absl::Status SetSubTaskBaseOptions(const ModelAssetBundleResources& resources, + HandLandmarkerGraphOptions* options, + bool is_copy) { + ASSIGN_OR_RETURN(const auto hand_detector_file, + resources.GetModelFile(kHandDetectorTFLiteName)); + SetExternalFile(hand_detector_file, + options->mutable_hand_detector_graph_options() + ->mutable_base_options() + ->mutable_model_asset(), + is_copy); + ASSIGN_OR_RETURN(const auto hand_landmarks_detector_file, + resources.GetModelFile(kHandLandmarksDetectorTFLiteName)); + SetExternalFile(hand_landmarks_detector_file, + options->mutable_hand_landmarks_detector_graph_options() + ->mutable_base_options() + ->mutable_model_asset(), + is_copy); + return absl::OkStatus(); +} + } // namespace // A "mediapipe.tasks.vision.hand_landmarker.HandLandmarkerGraph" performs hand @@ -154,6 +184,20 @@ class HandLandmarkerGraph : public core::ModelTaskGraph { absl::StatusOr GetConfig( SubgraphContext* sc) override { Graph graph; + if (sc->Options() + .base_options() + .has_model_asset()) { + ASSIGN_OR_RETURN( + const auto* model_asset_bundle_resources, + CreateModelAssetBundleResources(sc)); + // Copies the file content instead of passing the pointer of file in + // memory if the subgraph model resource service is not available. + MP_RETURN_IF_ERROR(SetSubTaskBaseOptions( + *model_asset_bundle_resources, + sc->MutableOptions(), + !sc->Service(::mediapipe::tasks::core::kModelResourcesCacheService) + .IsAvailable())); + } ASSIGN_OR_RETURN( auto hand_landmarker_outputs, BuildHandLandmarkerGraph(sc->Options(), diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph_test.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph_test.cc index bce5613ff..604f37d53 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph_test.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph_test.cc @@ -65,8 +65,7 @@ using ::testing::proto::Approximately; using ::testing::proto::Partially; constexpr char kTestDataDirectory[] = "/mediapipe/tasks/testdata/vision/"; -constexpr char kPalmDetectionModel[] = "palm_detection_full.tflite"; -constexpr char kHandLandmarkerFullModel[] = "hand_landmark_full.tflite"; +constexpr char kHandLandmarkerModelBundle[] = "hand_landmark.task"; constexpr char kLeftHandsImage[] = "left_hands.jpg"; constexpr char kImageTag[] = "IMAGE"; @@ -105,17 +104,9 @@ absl::StatusOr> CreateTaskRunner() { "mediapipe.tasks.vision.hand_landmarker.HandLandmarkerGraph"); auto& options = hand_landmarker_graph.GetOptions(); - options.mutable_hand_detector_graph_options() - ->mutable_base_options() - ->mutable_model_asset() - ->set_file_name(JoinPath("./", kTestDataDirectory, kPalmDetectionModel)); - options.mutable_hand_detector_graph_options()->mutable_base_options(); + options.mutable_base_options()->mutable_model_asset()->set_file_name( + JoinPath("./", kTestDataDirectory, kHandLandmarkerModelBundle)); options.mutable_hand_detector_graph_options()->set_num_hands(kMaxNumHands); - options.mutable_hand_landmarks_detector_graph_options() - ->mutable_base_options() - ->mutable_model_asset() - ->set_file_name( - JoinPath("./", kTestDataDirectory, kHandLandmarkerFullModel)); options.set_min_tracking_confidence(kMinTrackingConfidence); graph[Input(kImageTag)].SetName(kImageName) >> diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarker_graph_options.proto b/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarker_graph_options.proto index c985fc7fa..51e4e129a 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarker_graph_options.proto +++ b/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarker_graph_options.proto @@ -29,8 +29,8 @@ message HandLandmarkerGraphOptions { extend mediapipe.CalculatorOptions { optional HandLandmarkerGraphOptions ext = 462713202; } - // Base options for configuring MediaPipe Tasks, such as specifying the TfLite - // model file with metadata, accelerator options, etc. + // Base options for configuring MediaPipe Tasks, such as specifying the model + // asset bundle file with metadata, accelerator options, etc. optional core.proto.BaseOptions base_options = 1; // Options for hand detector graph. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizer.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizer.java index cc8346d80..128f6eab3 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizer.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizer.java @@ -433,8 +433,7 @@ public final class GestureRecognizer extends BaseVisionTaskApi { HandLandmarkerGraphOptionsProto.HandLandmarkerGraphOptions.newBuilder() .setBaseOptions( BaseOptionsProto.BaseOptions.newBuilder() - .setUseStreamMode(runningMode() != RunningMode.IMAGE) - .mergeFrom(convertBaseOptionsToProto(baseOptionsHandLandmarker()))); + .setUseStreamMode(runningMode() != RunningMode.IMAGE)); minTrackingConfidence() .ifPresent(handLandmarkerGraphOptionsBuilder::setMinTrackingConfidence); handLandmarkerGraphOptionsBuilder diff --git a/mediapipe/tasks/testdata/vision/BUILD b/mediapipe/tasks/testdata/vision/BUILD index 764b93c91..0532458aa 100644 --- a/mediapipe/tasks/testdata/vision/BUILD +++ b/mediapipe/tasks/testdata/vision/BUILD @@ -35,6 +35,7 @@ mediapipe_files(srcs = [ "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.tflite", "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29_with_dummy_score_calibration.tflite", "deeplabv3.tflite", + "hand_landmark.task", "hand_landmark_full.tflite", "hand_landmark_lite.tflite", "left_hands.jpg", @@ -109,6 +110,7 @@ filegroup( "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.tflite", "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29_with_dummy_score_calibration.tflite", "deeplabv3.tflite", + "hand_landmark.task", "hand_landmark_full.tflite", "hand_landmark_lite.tflite", "mobilenet_v1_0.25_192_quantized_1_default_1.tflite", diff --git a/mediapipe/tasks/testdata/vision/hand_landmark.task b/mediapipe/tasks/testdata/vision/hand_landmark.task new file mode 100644 index 000000000..b6eedf324 Binary files /dev/null and b/mediapipe/tasks/testdata/vision/hand_landmark.task differ diff --git a/third_party/external_files.bzl b/third_party/external_files.bzl index b42019a17..b85d93318 100644 --- a/third_party/external_files.bzl +++ b/third_party/external_files.bzl @@ -268,6 +268,12 @@ def external_files(): urls = ["https://storage.googleapis.com/mediapipe-assets/hand_landmark_lite.tflite?generation=1661875766398729"], ) + http_file( + name = "com_google_mediapipe_hand_landmark_task", + sha256 = "dd830295598e48e6bbbdf22fd9e69538fa07768106cd9ceb04d5462ca7e38c95", + urls = ["https://storage.googleapis.com/mediapipe-assets/hand_landmark.task?generation=1665707323647357"], + ) + http_file( name = "com_google_mediapipe_hand_recrop_tflite", sha256 = "67d996ce96f9d36fe17d2693022c6da93168026ab2f028f9e2365398d8ac7d5d",