Merged ios-ml-image with master
This commit is contained in:
commit
0e944cb764
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
name: "Build/Installation Issue"
|
|
||||||
about: Use this template for build/installation issues
|
|
||||||
labels: type:build/install
|
|
||||||
|
|
||||||
---
|
|
||||||
<em>Please make sure that this is a build/installation issue and also refer to the [troubleshooting](https://google.github.io/mediapipe/getting_started/troubleshooting.html) documentation before raising any issues.</em>
|
|
||||||
|
|
||||||
**System information** (Please provide as much relevant information as possible)
|
|
||||||
- OS Platform and Distribution (e.g. Linux Ubuntu 16.04, Android 11, iOS 14.4):
|
|
||||||
- Compiler version (e.g. gcc/g++ 8 /Apple clang version 12.0.0):
|
|
||||||
- Programming Language and version ( e.g. C++ 14, Python 3.6, Java ):
|
|
||||||
- Installed using virtualenv? pip? Conda? (if python):
|
|
||||||
- [MediaPipe version](https://github.com/google/mediapipe/releases):
|
|
||||||
- Bazel version:
|
|
||||||
- XCode and Tulsi versions (if iOS):
|
|
||||||
- Android SDK and NDK versions (if android):
|
|
||||||
- Android [AAR](https://google.github.io/mediapipe/getting_started/android_archive_library.html) ( if android):
|
|
||||||
- OpenCV version (if running on desktop):
|
|
||||||
|
|
||||||
**Describe the problem**:
|
|
||||||
|
|
||||||
|
|
||||||
**[Provide the exact sequence of commands / steps that you executed before running into the problem](https://google.github.io/mediapipe/getting_started/getting_started.html):**
|
|
||||||
|
|
||||||
**Complete Logs:**
|
|
||||||
Include Complete Log information or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached:
|
|
25
.github/ISSUE_TEMPLATE/11-tasks-issue.md
vendored
25
.github/ISSUE_TEMPLATE/11-tasks-issue.md
vendored
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
name: "Tasks Issue"
|
|
||||||
about: Use this template for assistance with using MediaPipe Tasks (developers.google.com/mediapipe/solutions) to deploy on-device ML solutions (e.g. gesture recognition etc.) on supported platforms.
|
|
||||||
labels: type:support
|
|
||||||
|
|
||||||
---
|
|
||||||
<em>Please make sure that this is a [Tasks](https://developers.google.com/mediapipe/solutions) issue.<em>
|
|
||||||
|
|
||||||
**System information** (Please provide as much relevant information as possible)
|
|
||||||
- Have I written custom code (as opposed to using a stock example script provided in MediaPipe):
|
|
||||||
- OS Platform and Distribution (e.g., Linux Ubuntu 16.04, Android 11, iOS 14.4):
|
|
||||||
- MediaPipe Tasks SDK version:
|
|
||||||
- Task name (e.g. Object detection, Gesture recognition etc.):
|
|
||||||
- Programming Language and version ( e.g. C++, Python, Java):
|
|
||||||
|
|
||||||
**Describe the expected behavior:**
|
|
||||||
|
|
||||||
**Standalone code you may have used to try to get what you need :**
|
|
||||||
|
|
||||||
If there is a problem, provide a reproducible test case that is the bare minimum necessary to generate the problem. If possible, please share a link to Colab, GitHub repo link or anything that we can use to reproduce the problem:
|
|
||||||
|
|
||||||
**Other info / Complete Logs :**
|
|
||||||
Include any logs or source code that would be helpful to
|
|
||||||
diagnose the problem. If including tracebacks, please include the full
|
|
||||||
traceback. Large logs and files should be attached:
|
|
25
.github/ISSUE_TEMPLATE/12-model-maker-issue.md
vendored
25
.github/ISSUE_TEMPLATE/12-model-maker-issue.md
vendored
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
name: "Model Maker Issue"
|
|
||||||
about: Use this template for assistance with using MediaPipe Model Maker (developers.google.com/mediapipe/solutions) to create custom on-device ML solutions.
|
|
||||||
labels: type:support
|
|
||||||
|
|
||||||
---
|
|
||||||
<em>Please make sure that this is a [Model Maker](https://developers.google.com/mediapipe/solutions) issue.<em>
|
|
||||||
|
|
||||||
**System information** (Please provide as much relevant information as possible)
|
|
||||||
- Have I written custom code (as opposed to using a stock example script provided in MediaPipe):
|
|
||||||
- OS Platform and Distribution (e.g., Linux Ubuntu 16.04):
|
|
||||||
- Python version (e.g. 3.8):
|
|
||||||
- [MediaPipe Model Maker version](https://pypi.org/project/mediapipe-model-maker/):
|
|
||||||
- Task name (e.g. Image classification, Gesture recognition etc.):
|
|
||||||
|
|
||||||
**Describe the expected behavior:**
|
|
||||||
|
|
||||||
**Standalone code you may have used to try to get what you need :**
|
|
||||||
|
|
||||||
If there is a problem, provide a reproducible test case that is the bare minimum necessary to generate the problem. If possible, please share a link to Colab, GitHub repo link or anything that we can use to reproduce the problem:
|
|
||||||
|
|
||||||
**Other info / Complete Logs :**
|
|
||||||
Include any logs or source code that would be helpful to
|
|
||||||
diagnose the problem. If including tracebacks, please include the full
|
|
||||||
traceback. Large logs and files should be attached:
|
|
26
.github/ISSUE_TEMPLATE/13-solution-issue.md
vendored
26
.github/ISSUE_TEMPLATE/13-solution-issue.md
vendored
|
@ -1,26 +0,0 @@
|
||||||
---
|
|
||||||
name: "Solution (legacy) Issue"
|
|
||||||
about: Use this template for assistance with a specific Mediapipe solution (google.github.io/mediapipe/solutions) such as "Pose", including inference model usage/training, solution-specific calculators etc.
|
|
||||||
labels: type:support
|
|
||||||
|
|
||||||
---
|
|
||||||
<em>Please make sure that this is a [solution](https://google.github.io/mediapipe/solutions/solutions.html) issue.<em>
|
|
||||||
|
|
||||||
**System information** (Please provide as much relevant information as possible)
|
|
||||||
- Have I written custom code (as opposed to using a stock example script provided in Mediapipe):
|
|
||||||
- OS Platform and Distribution (e.g., Linux Ubuntu 16.04, Android 11, iOS 14.4):
|
|
||||||
- [MediaPipe version](https://github.com/google/mediapipe/releases):
|
|
||||||
- Bazel version:
|
|
||||||
- Solution (e.g. FaceMesh, Pose, Holistic):
|
|
||||||
- Programming Language and version ( e.g. C++, Python, Java):
|
|
||||||
|
|
||||||
**Describe the expected behavior:**
|
|
||||||
|
|
||||||
**Standalone code you may have used to try to get what you need :**
|
|
||||||
|
|
||||||
If there is a problem, provide a reproducible test case that is the bare minimum necessary to generate the problem. If possible, please share a link to Colab/repo link /any notebook:
|
|
||||||
|
|
||||||
**Other info / Complete Logs :**
|
|
||||||
Include any logs or source code that would be helpful to
|
|
||||||
diagnose the problem. If including tracebacks, please include the full
|
|
||||||
traceback. Large logs and files should be attached:
|
|
19
.github/ISSUE_TEMPLATE/14-studio-issue.md
vendored
19
.github/ISSUE_TEMPLATE/14-studio-issue.md
vendored
|
@ -1,19 +0,0 @@
|
||||||
---
|
|
||||||
name: "Studio Issue"
|
|
||||||
about: Use this template for assistance with the MediaPipe Studio application.
|
|
||||||
labels: type:support
|
|
||||||
|
|
||||||
---
|
|
||||||
<em>Please make sure that this is a MediaPipe Studio issue.<em>
|
|
||||||
|
|
||||||
**System information** (Please provide as much relevant information as possible)
|
|
||||||
- OS Platform and Distribution (e.g., Linux Ubuntu 16.04, Android 11, iOS 14.4):
|
|
||||||
- Browser and Version
|
|
||||||
- Any microphone or camera hardware
|
|
||||||
- URL that shows the problem
|
|
||||||
|
|
||||||
**Describe the expected behavior:**
|
|
||||||
|
|
||||||
**Other info / Complete Logs :**
|
|
||||||
Include any js console logs that would be helpful to diagnose the problem.
|
|
||||||
Large logs and files should be attached:
|
|
51
.github/ISSUE_TEMPLATE/20-documentation-issue.md
vendored
51
.github/ISSUE_TEMPLATE/20-documentation-issue.md
vendored
|
@ -1,51 +0,0 @@
|
||||||
---
|
|
||||||
name: "Documentation Issue"
|
|
||||||
about: Use this template for documentation related issues
|
|
||||||
labels: type:docs
|
|
||||||
|
|
||||||
---
|
|
||||||
Thank you for submitting a MediaPipe documentation issue.
|
|
||||||
The MediaPipe docs are open source! To get involved, read the documentation Contributor Guide
|
|
||||||
## URL(s) with the issue:
|
|
||||||
|
|
||||||
Please provide a link to the documentation entry, for example: https://github.com/google/mediapipe/blob/master/docs/solutions/face_mesh.md#models
|
|
||||||
|
|
||||||
## Description of issue (what needs changing):
|
|
||||||
|
|
||||||
Kinds of documentation problems:
|
|
||||||
|
|
||||||
### Clear description
|
|
||||||
|
|
||||||
For example, why should someone use this method? How is it useful?
|
|
||||||
|
|
||||||
### Correct links
|
|
||||||
|
|
||||||
Is the link to the source code correct?
|
|
||||||
|
|
||||||
### Parameters defined
|
|
||||||
Are all parameters defined and formatted correctly?
|
|
||||||
|
|
||||||
### Returns defined
|
|
||||||
|
|
||||||
Are return values defined?
|
|
||||||
|
|
||||||
### Raises listed and defined
|
|
||||||
|
|
||||||
Are the errors defined? For example,
|
|
||||||
|
|
||||||
### Usage example
|
|
||||||
|
|
||||||
Is there a usage example?
|
|
||||||
|
|
||||||
See the API guide:
|
|
||||||
on how to write testable usage examples.
|
|
||||||
|
|
||||||
### Request visuals, if applicable
|
|
||||||
|
|
||||||
Are there currently visuals? If not, will it clarify the content?
|
|
||||||
|
|
||||||
### Submit a pull request?
|
|
||||||
|
|
||||||
Are you planning to also submit a pull request to fix the issue? See the docs
|
|
||||||
https://github.com/google/mediapipe/blob/master/CONTRIBUTING.md
|
|
||||||
|
|
32
.github/ISSUE_TEMPLATE/30-bug-issue.md
vendored
32
.github/ISSUE_TEMPLATE/30-bug-issue.md
vendored
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
name: "Bug Issue"
|
|
||||||
about: Use this template for reporting a bug
|
|
||||||
labels: type:bug
|
|
||||||
|
|
||||||
---
|
|
||||||
<em>Please make sure that this is a bug and also refer to the [troubleshooting](https://google.github.io/mediapipe/getting_started/troubleshooting.html), FAQ documentation before raising any issues.</em>
|
|
||||||
|
|
||||||
**System information** (Please provide as much relevant information as possible)
|
|
||||||
|
|
||||||
- Have I written custom code (as opposed to using a stock example script provided in MediaPipe):
|
|
||||||
- OS Platform and Distribution (e.g., Linux Ubuntu 16.04, Android 11, iOS 14.4):
|
|
||||||
- Mobile device (e.g. iPhone 8, Pixel 2, Samsung Galaxy) if the issue happens on mobile device:
|
|
||||||
- Browser and version (e.g. Google Chrome, Safari) if the issue happens on browser:
|
|
||||||
- Programming Language and version ( e.g. C++, Python, Java):
|
|
||||||
- [MediaPipe version](https://github.com/google/mediapipe/releases):
|
|
||||||
- Bazel version (if compiling from source):
|
|
||||||
- Solution ( e.g. FaceMesh, Pose, Holistic ):
|
|
||||||
- Android Studio, NDK, SDK versions (if issue is related to building in Android environment):
|
|
||||||
- Xcode & Tulsi version (if issue is related to building for iOS):
|
|
||||||
|
|
||||||
**Describe the current behavior:**
|
|
||||||
|
|
||||||
**Describe the expected behavior:**
|
|
||||||
|
|
||||||
**Standalone code to reproduce the issue:**
|
|
||||||
Provide a reproducible test case that is the bare minimum necessary to replicate the problem. If possible, please share a link to Colab/repo link /any notebook:
|
|
||||||
|
|
||||||
**Other info / Complete Logs :**
|
|
||||||
Include any logs or source code that would be helpful to
|
|
||||||
diagnose the problem. If including tracebacks, please include the full
|
|
||||||
traceback. Large logs and files should be attached
|
|
24
.github/ISSUE_TEMPLATE/40-feature-request.md
vendored
24
.github/ISSUE_TEMPLATE/40-feature-request.md
vendored
|
@ -1,24 +0,0 @@
|
||||||
---
|
|
||||||
name: "Feature Request"
|
|
||||||
about: Use this template for raising a feature request
|
|
||||||
labels: type:feature
|
|
||||||
|
|
||||||
---
|
|
||||||
<em>Please make sure that this is a feature request.</em>
|
|
||||||
|
|
||||||
**System information** (Please provide as much relevant information as possible)
|
|
||||||
|
|
||||||
- MediaPipe Solution (you are using):
|
|
||||||
- Programming language : C++/typescript/Python/Objective C/Android Java
|
|
||||||
- Are you willing to contribute it (Yes/No):
|
|
||||||
|
|
||||||
|
|
||||||
**Describe the feature and the current behavior/state:**
|
|
||||||
|
|
||||||
**Will this change the current api? How?**
|
|
||||||
|
|
||||||
**Who will benefit with this feature?**
|
|
||||||
|
|
||||||
**Please specify the use cases for this feature:**
|
|
||||||
|
|
||||||
**Any Other info:**
|
|
73
.github/ISSUE_TEMPLATE/Documentation_issue_template.yaml
vendored
Normal file
73
.github/ISSUE_TEMPLATE/Documentation_issue_template.yaml
vendored
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
name: Documentation issue
|
||||||
|
description: Use this template for documentation related issues. If this doesn’t look right, choose a different type.
|
||||||
|
labels: 'type:doc-bug'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: link
|
||||||
|
attributes:
|
||||||
|
value: Thank you for submitting a MediaPipe documentation issue. The MediaPipe docs are open source! To get involved, read the documentation Contributor Guide
|
||||||
|
- type: markdown
|
||||||
|
id: url
|
||||||
|
attributes:
|
||||||
|
value: URL(s) with the issue Please provide a link to the documentation entry, for example https://github.com/google/mediapipe/blob/master/docs/solutions/face_mesh.md#models
|
||||||
|
- type: input
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Description of issue (what needs changing)
|
||||||
|
description: Kinds of documentation problems
|
||||||
|
- type: input
|
||||||
|
id: clear_desc
|
||||||
|
attributes:
|
||||||
|
label: Clear description
|
||||||
|
description: For example, why should someone use this method? How is it useful?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: link
|
||||||
|
attributes:
|
||||||
|
label: Correct links
|
||||||
|
description: Is the link to the source code correct?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: parameter
|
||||||
|
attributes:
|
||||||
|
label: Parameters defined
|
||||||
|
description: Are all parameters defined and formatted correctly?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: returns
|
||||||
|
attributes:
|
||||||
|
label: Returns defined
|
||||||
|
description: Are return values defined?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: raises
|
||||||
|
attributes:
|
||||||
|
label: Raises listed and defined
|
||||||
|
description: Are the errors defined? For example,
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: usage
|
||||||
|
attributes:
|
||||||
|
label: Usage example
|
||||||
|
description: Is there a usage example? See the API guide-on how to write testable usage examples.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: visual
|
||||||
|
attributes:
|
||||||
|
label: Request visuals, if applicable
|
||||||
|
description: Are there currently visuals? If not, will it clarify the content?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: pull
|
||||||
|
attributes:
|
||||||
|
label: Submit a pull request?
|
||||||
|
description: Are you planning to also submit a pull request to fix the issue? See the [docs](https://github.com/google/mediapipe/blob/master/CONTRIBUTING.md)
|
||||||
|
validations:
|
||||||
|
required: false
|
80
.github/ISSUE_TEMPLATE/Solution(Legacy_issue_template).yaml
vendored
Normal file
80
.github/ISSUE_TEMPLATE/Solution(Legacy_issue_template).yaml
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
name: Solution(Legacy) Issue
|
||||||
|
description: Use this template for assistance with a specific Mediapipe solution (google.github.io/mediapipe/solutions) such as "Pose", including inference model usage/training, solution-specific calculators etc.
|
||||||
|
labels: 'type:support'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: linkmodel
|
||||||
|
attributes:
|
||||||
|
value: Please make sure that this is a [solution](https://google.github.io/mediapipe/solutions/solutions.html) issue.
|
||||||
|
- type: dropdown
|
||||||
|
id: customcode_model
|
||||||
|
attributes:
|
||||||
|
label: Have I written custom code (as opposed to using a stock example script provided in MediaPipe)
|
||||||
|
options:
|
||||||
|
- 'Yes'
|
||||||
|
- 'No'
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: os_model
|
||||||
|
attributes:
|
||||||
|
label: OS Platform and Distribution
|
||||||
|
placeholder: e.g. Linux Ubuntu 16.04, Android 11, iOS 14.4
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: mediapipe_version
|
||||||
|
attributes:
|
||||||
|
label: MediaPipe version
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: bazel_version
|
||||||
|
attributes:
|
||||||
|
label: Bazel version
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: solution
|
||||||
|
attributes:
|
||||||
|
label: Solution
|
||||||
|
placeholder: e.g. FaceMesh, Pose, Holistic
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: programminglang
|
||||||
|
attributes:
|
||||||
|
label: Programming Language and version
|
||||||
|
placeholder: e.g. C++, Python, Java
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: current_model
|
||||||
|
attributes:
|
||||||
|
label: Describe the actual behavior
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: expected_model
|
||||||
|
attributes:
|
||||||
|
label: Describe the expected behaviour
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened_model
|
||||||
|
attributes:
|
||||||
|
label: Standalone code/steps you may have used to try to get what you need
|
||||||
|
description: If there is a problem, provide a reproducible test case that is the bare minimum necessary to generate the problem. If possible, please share a link to Colab, GitHub repo link or anything that we can use to reproduce the problem
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: other_info
|
||||||
|
attributes:
|
||||||
|
label: Other info / Complete Logs
|
||||||
|
description: Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
112
.github/ISSUE_TEMPLATE/bug_issue_template.yaml
vendored
Normal file
112
.github/ISSUE_TEMPLATE/bug_issue_template.yaml
vendored
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
name: Bug Issues
|
||||||
|
description: Use this template for reporting a bug. If this doesn’t look right, choose a different type.
|
||||||
|
labels: 'type:bug'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: link
|
||||||
|
attributes:
|
||||||
|
value: Please make sure that this is a bug and also refer to the [troubleshooting](https://google.github.io/mediapipe/getting_started/troubleshooting.html), FAQ documentation before raising any issues.
|
||||||
|
- type: dropdown
|
||||||
|
id: customcode_model
|
||||||
|
attributes:
|
||||||
|
label: Have I written custom code (as opposed to using a stock example script provided in MediaPipe)
|
||||||
|
options:
|
||||||
|
- 'Yes'
|
||||||
|
- 'No'
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: os
|
||||||
|
attributes:
|
||||||
|
label: OS Platform and Distribution
|
||||||
|
description:
|
||||||
|
placeholder: e.g. Linux Ubuntu 16.04, Android 11, iOS 14.4
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: mobile_device
|
||||||
|
attributes:
|
||||||
|
label: Mobile device if the issue happens on mobile device
|
||||||
|
description:
|
||||||
|
placeholder: e.g. iPhone 8, Pixel 2, Samsung Galaxy
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: browser_version
|
||||||
|
attributes:
|
||||||
|
label: Browser and version if the issue happens on browser
|
||||||
|
placeholder: e.g. Google Chrome 109.0.5414.119, Safari 16.3
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: programminglang
|
||||||
|
attributes:
|
||||||
|
label: Programming Language and version
|
||||||
|
placeholder: e.g. C++, Python, Java
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: mediapipever
|
||||||
|
attributes:
|
||||||
|
label: MediaPipe version
|
||||||
|
description:
|
||||||
|
placeholder: e.g. 0.8.11, 0.9.1
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: bazelver
|
||||||
|
attributes:
|
||||||
|
label: Bazel version
|
||||||
|
description:
|
||||||
|
placeholder: e.g. 5.0, 5.1
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: solution
|
||||||
|
attributes:
|
||||||
|
label: Solution
|
||||||
|
placeholder: e.g. FaceMesh, Pose, Holistic
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: sdkndkversion
|
||||||
|
attributes:
|
||||||
|
label: Android Studio, NDK, SDK versions (if issue is related to building in Android environment)
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: xcode_ver
|
||||||
|
attributes:
|
||||||
|
label: Xcode & Tulsi version (if issue is related to building for iOS)
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: current_model
|
||||||
|
attributes:
|
||||||
|
label: Describe the actual behavior
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: expected_model
|
||||||
|
attributes:
|
||||||
|
label: Describe the expected behaviour
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened_model
|
||||||
|
attributes:
|
||||||
|
label: Standalone code/steps you may have used to try to get what you need
|
||||||
|
description: If there is a problem, provide a reproducible test case that is the bare minimum necessary to generate the problem. If possible, please share a link to Colab, GitHub repo link or anything that we can use to reproduce the problem
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: other_info
|
||||||
|
attributes:
|
||||||
|
label: Other info / Complete Logs
|
||||||
|
description: Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
109
.github/ISSUE_TEMPLATE/build.install_issue_template.yaml
vendored
Normal file
109
.github/ISSUE_TEMPLATE/build.install_issue_template.yaml
vendored
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
name: Build/Install Issue
|
||||||
|
description: Use this template to report build/install issue
|
||||||
|
labels: 'type:build/install'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: link
|
||||||
|
attributes:
|
||||||
|
value: Please make sure that this is a build/installation issue and also refer to the [troubleshooting](https://google.github.io/mediapipe/getting_started/troubleshooting.html) documentation before raising any issues.
|
||||||
|
- type: input
|
||||||
|
id: os
|
||||||
|
attributes:
|
||||||
|
label: OS Platform and Distribution
|
||||||
|
description:
|
||||||
|
placeholder: e.g. Linux Ubuntu 16.04, Android 11, iOS 14.4
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: compilerversion
|
||||||
|
attributes:
|
||||||
|
label: Compiler version
|
||||||
|
description:
|
||||||
|
placeholder: e.g. gcc/g++ 8 /Apple clang version 12.0.0
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: programminglang
|
||||||
|
attributes:
|
||||||
|
label: Programming Language and version
|
||||||
|
description:
|
||||||
|
placeholder: e.g. C++ 14, Python 3.6, Java
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: virtualenv
|
||||||
|
attributes:
|
||||||
|
label: Installed using virtualenv? pip? Conda?(if python)
|
||||||
|
description:
|
||||||
|
placeholder:
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: mediapipever
|
||||||
|
attributes:
|
||||||
|
label: MediaPipe version
|
||||||
|
description:
|
||||||
|
placeholder: e.g. 0.8.11, 0.9.1
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: bazelver
|
||||||
|
attributes:
|
||||||
|
label: Bazel version
|
||||||
|
description:
|
||||||
|
placeholder: e.g. 5.0, 5.1
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: xcodeversion
|
||||||
|
attributes:
|
||||||
|
label: XCode and Tulsi versions (if iOS)
|
||||||
|
description:
|
||||||
|
placeholder:
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: sdkndkversion
|
||||||
|
attributes:
|
||||||
|
label: Android SDK and NDK versions (if android)
|
||||||
|
description:
|
||||||
|
placeholder:
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: dropdown
|
||||||
|
id: androidaar
|
||||||
|
attributes:
|
||||||
|
label: Android AAR (if android)
|
||||||
|
options:
|
||||||
|
- 'Yes'
|
||||||
|
- 'No'
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: opencvversion
|
||||||
|
attributes:
|
||||||
|
label: OpenCV version (if running on desktop)
|
||||||
|
description:
|
||||||
|
placeholder:
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened
|
||||||
|
attributes:
|
||||||
|
label: Describe the problem
|
||||||
|
description: Provide the exact sequence of commands / steps that you executed before running into the [problem](https://google.github.io/mediapipe/getting_started/getting_started.html)
|
||||||
|
placeholder: Tell us what you see!
|
||||||
|
value: "A bug happened!"
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: code-to-reproduce
|
||||||
|
attributes:
|
||||||
|
label: Complete Logs
|
||||||
|
description: Include Complete Log information or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached
|
||||||
|
placeholder: Tell us what you see!
|
||||||
|
value:
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
64
.github/ISSUE_TEMPLATE/feature_request_issue_template.yaml
vendored
Normal file
64
.github/ISSUE_TEMPLATE/feature_request_issue_template.yaml
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
name: Feature Request Issues
|
||||||
|
description: Use this template for raising a feature request. If this doesn’t look right, choose a different type.
|
||||||
|
labels: 'type:feature'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: linkmodel
|
||||||
|
attributes:
|
||||||
|
value: Please make sure that this is a feature request.
|
||||||
|
- type: input
|
||||||
|
id: solution
|
||||||
|
attributes:
|
||||||
|
label: MediaPipe Solution (you are using)
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: pgmlang
|
||||||
|
attributes:
|
||||||
|
label: Programming language
|
||||||
|
placeholder: C++/typescript/Python/Objective C/Android Java
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: dropdown
|
||||||
|
id: willingcon
|
||||||
|
attributes:
|
||||||
|
label: Are you willing to contribute it
|
||||||
|
options:
|
||||||
|
- 'Yes'
|
||||||
|
- 'No'
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: behaviour
|
||||||
|
attributes:
|
||||||
|
label: Describe the feature and the current behaviour/state
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: api_change
|
||||||
|
attributes:
|
||||||
|
label: Will this change the current API? How?
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: benifit
|
||||||
|
attributes:
|
||||||
|
label: Who will benefit with this feature?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: use_case
|
||||||
|
attributes:
|
||||||
|
label: Please specify the use cases for this feature
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: info_other
|
||||||
|
attributes:
|
||||||
|
label: Any Other info
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
73
.github/ISSUE_TEMPLATE/model_maker_issue_template.yaml
vendored
Normal file
73
.github/ISSUE_TEMPLATE/model_maker_issue_template.yaml
vendored
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
name: Model Maker Issues
|
||||||
|
description: Use this template for assistance with using MediaPipe Model Maker (developers.google.com/mediapipe/solutions) to create custom on-device ML solutions.
|
||||||
|
labels: 'type:modelmaker'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: linkmodel
|
||||||
|
attributes:
|
||||||
|
value: Please make sure that this is a [Model Maker](https://developers.google.com/mediapipe/solutions) issue
|
||||||
|
- type: dropdown
|
||||||
|
id: customcode_model
|
||||||
|
attributes:
|
||||||
|
label: Have I written custom code (as opposed to using a stock example script provided in MediaPipe)
|
||||||
|
options:
|
||||||
|
- 'Yes'
|
||||||
|
- 'No'
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: os_model
|
||||||
|
attributes:
|
||||||
|
label: OS Platform and Distribution
|
||||||
|
placeholder: e.g. Linux Ubuntu 16.04, Android 11, iOS 14.4
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: pythonver
|
||||||
|
attributes:
|
||||||
|
label: Python Version
|
||||||
|
placeholder: e.g. 3.7, 3.8
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: modelmakerver
|
||||||
|
attributes:
|
||||||
|
label: MediaPipe Model Maker version
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: taskname
|
||||||
|
attributes:
|
||||||
|
label: Task name (e.g. Image classification, Gesture recognition etc.)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: current_model
|
||||||
|
attributes:
|
||||||
|
label: Describe the actual behavior
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: expected_model
|
||||||
|
attributes:
|
||||||
|
label: Describe the expected behaviour
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened_model
|
||||||
|
attributes:
|
||||||
|
label: Standalone code/steps you may have used to try to get what you need
|
||||||
|
description: If there is a problem, provide a reproducible test case that is the bare minimum necessary to generate the problem. If possible, please share a link to Colab, GitHub repo link or anything that we can use to reproduce the problem
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: other_info
|
||||||
|
attributes:
|
||||||
|
label: Other info / Complete Logs
|
||||||
|
description: Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
63
.github/ISSUE_TEMPLATE/studio_issue_template.yaml
vendored
Normal file
63
.github/ISSUE_TEMPLATE/studio_issue_template.yaml
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
name: Studio Issues
|
||||||
|
description: Use this template for assistance with the MediaPipe Studio application. If this doesn’t look right, choose a different type.
|
||||||
|
labels: 'type:support'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: linkmodel
|
||||||
|
attributes:
|
||||||
|
value: Please make sure that this is a MediaPipe Studio issue.
|
||||||
|
- type: input
|
||||||
|
id: os_model
|
||||||
|
attributes:
|
||||||
|
label: OS Platform and Distribution
|
||||||
|
placeholder: e.g. Linux Ubuntu 16.04, Android 11, iOS 14.4
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: browserver
|
||||||
|
attributes:
|
||||||
|
label: Browser and Version
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: hardware
|
||||||
|
attributes:
|
||||||
|
label: Any microphone or camera hardware
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: url
|
||||||
|
attributes:
|
||||||
|
label: URL that shows the problem
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: current_model
|
||||||
|
attributes:
|
||||||
|
label: Describe the actual behavior
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: expected_model
|
||||||
|
attributes:
|
||||||
|
label: Describe the expected behaviour
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened_model
|
||||||
|
attributes:
|
||||||
|
label: Standalone code/steps you may have used to try to get what you need
|
||||||
|
description: If there is a problem, provide a reproducible test case that is the bare minimum necessary to generate the problem. If possible, please share a link to Colab, GitHub repo link or anything that we can use to reproduce the problem
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: other_info
|
||||||
|
attributes:
|
||||||
|
label: Other info / Complete Logs
|
||||||
|
description: Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
72
.github/ISSUE_TEMPLATE/task_issue_template.yaml
vendored
Normal file
72
.github/ISSUE_TEMPLATE/task_issue_template.yaml
vendored
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
name: Task Issue
|
||||||
|
description: Use this template for assistance with using MediaPipe Tasks (developers.google.com/mediapipe/solutions) to deploy on-device ML solutions (e.g. gesture recognition etc.) on supported platforms
|
||||||
|
labels: 'type:task'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: linkmodel
|
||||||
|
attributes:
|
||||||
|
value: Please make sure that this is a [Tasks](https://developers.google.com/mediapipe/solutions) issue.
|
||||||
|
- type: dropdown
|
||||||
|
id: customcode_model
|
||||||
|
attributes:
|
||||||
|
label: Have I written custom code (as opposed to using a stock example script provided in MediaPipe)
|
||||||
|
options:
|
||||||
|
- 'Yes'
|
||||||
|
- 'No'
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: os_model
|
||||||
|
attributes:
|
||||||
|
label: OS Platform and Distribution
|
||||||
|
placeholder: e.g. Linux Ubuntu 16.04, Android 11, iOS 14.4
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: task-sdk-version
|
||||||
|
attributes:
|
||||||
|
label: MediaPipe Tasks SDK version
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: taskname
|
||||||
|
attributes:
|
||||||
|
label: Task name (e.g. Image classification, Gesture recognition etc.)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: programminglang
|
||||||
|
attributes:
|
||||||
|
label: Programming Language and version (e.g. C++, Python, Java)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: current_model
|
||||||
|
attributes:
|
||||||
|
label: Describe the actual behavior
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: expected_model
|
||||||
|
attributes:
|
||||||
|
label: Describe the expected behaviour
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened_model
|
||||||
|
attributes:
|
||||||
|
label: Standalone code/steps you may have used to try to get what you need
|
||||||
|
description: If there is a problem, provide a reproducible test case that is the bare minimum necessary to generate the problem. If possible, please share a link to Colab, GitHub repo link or anything that we can use to reproduce the problem
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: other_info
|
||||||
|
attributes:
|
||||||
|
label: Other info / Complete Logs
|
||||||
|
description: Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached
|
||||||
|
render: shell
|
||||||
|
validations:
|
||||||
|
required: false
|
13
WORKSPACE
13
WORKSPACE
|
@ -10,12 +10,11 @@ bind(
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "bazel_skylib",
|
name = "bazel_skylib",
|
||||||
type = "tar.gz",
|
sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506",
|
||||||
urls = [
|
urls = [
|
||||||
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
|
"https://storage.googleapis.com/mirror.tensorflow.org/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
|
||||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
|
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
|
||||||
],
|
],
|
||||||
sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c",
|
|
||||||
)
|
)
|
||||||
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
|
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
|
||||||
bazel_skylib_workspace()
|
bazel_skylib_workspace()
|
||||||
|
@ -455,9 +454,9 @@ http_archive(
|
||||||
)
|
)
|
||||||
|
|
||||||
# TensorFlow repo should always go after the other external dependencies.
|
# TensorFlow repo should always go after the other external dependencies.
|
||||||
# TF on 2022-08-10.
|
# TF on 2023-02-02.
|
||||||
_TENSORFLOW_GIT_COMMIT = "af1d5bc4fbb66d9e6cc1cf89503014a99233583b"
|
_TENSORFLOW_GIT_COMMIT = "581840e12c7762a3deef66b25a549218ca1e3983"
|
||||||
_TENSORFLOW_SHA256 = "f85a5443264fc58a12d136ca6a30774b5bc25ceaf7d114d97f252351b3c3a2cb"
|
_TENSORFLOW_SHA256 = "27f8f51e34b5065ac5411332eb4ad02f1d954257036d4863810d0c394d044bc9"
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "org_tensorflow",
|
name = "org_tensorflow",
|
||||||
urls = [
|
urls = [
|
||||||
|
|
|
@ -54,6 +54,25 @@ used for its improved inference speed. Please refer to the
|
||||||
[model cards](./models.md#face_detection) for details. Default to `0` if not
|
[model cards](./models.md#face_detection) for details. Default to `0` if not
|
||||||
specified.
|
specified.
|
||||||
|
|
||||||
|
Note: Not available for JavaScript (use "model" instead).
|
||||||
|
|
||||||
|
#### model
|
||||||
|
|
||||||
|
A string value to indicate which model should be used. Use "short" to
|
||||||
|
select a short-range model that works best for faces within 2 meters from the
|
||||||
|
camera, and "full" for a full-range model best for faces within 5 meters. For
|
||||||
|
the full-range option, a sparse model is used for its improved inference speed.
|
||||||
|
Please refer to the model cards for details. Default to empty string.
|
||||||
|
|
||||||
|
Note: Valid only for JavaScript solution.
|
||||||
|
|
||||||
|
#### selfie_mode
|
||||||
|
|
||||||
|
A boolean value to indicate whether to flip the images/video frames
|
||||||
|
horizontally or not. Default to `false`.
|
||||||
|
|
||||||
|
Note: Valid only for JavaScript solution.
|
||||||
|
|
||||||
#### min_detection_confidence
|
#### min_detection_confidence
|
||||||
|
|
||||||
Minimum confidence value (`[0.0, 1.0]`) from the face detection model for the
|
Minimum confidence value (`[0.0, 1.0]`) from the face detection model for the
|
||||||
|
@ -146,9 +165,9 @@ Please first see general [introduction](../getting_started/javascript.md) on
|
||||||
MediaPipe in JavaScript, then learn more in the companion [web demo](#resources)
|
MediaPipe in JavaScript, then learn more in the companion [web demo](#resources)
|
||||||
and the following usage example.
|
and the following usage example.
|
||||||
|
|
||||||
Supported configuration options:
|
Supported face detection options:
|
||||||
|
* [selfieMode](#selfie_mode)
|
||||||
* [modelSelection](#model_selection)
|
* [model](#model)
|
||||||
* [minDetectionConfidence](#min_detection_confidence)
|
* [minDetectionConfidence](#min_detection_confidence)
|
||||||
|
|
||||||
```html
|
```html
|
||||||
|
@ -176,6 +195,7 @@ Supported configuration options:
|
||||||
const videoElement = document.getElementsByClassName('input_video')[0];
|
const videoElement = document.getElementsByClassName('input_video')[0];
|
||||||
const canvasElement = document.getElementsByClassName('output_canvas')[0];
|
const canvasElement = document.getElementsByClassName('output_canvas')[0];
|
||||||
const canvasCtx = canvasElement.getContext('2d');
|
const canvasCtx = canvasElement.getContext('2d');
|
||||||
|
const drawingUtils = window;
|
||||||
|
|
||||||
function onResults(results) {
|
function onResults(results) {
|
||||||
// Draw the overlays.
|
// Draw the overlays.
|
||||||
|
@ -199,7 +219,7 @@ const faceDetection = new FaceDetection({locateFile: (file) => {
|
||||||
return `https://cdn.jsdelivr.net/npm/@mediapipe/face_detection@0.0/${file}`;
|
return `https://cdn.jsdelivr.net/npm/@mediapipe/face_detection@0.0/${file}`;
|
||||||
}});
|
}});
|
||||||
faceDetection.setOptions({
|
faceDetection.setOptions({
|
||||||
modelSelection: 0,
|
model: 'short',
|
||||||
minDetectionConfidence: 0.5
|
minDetectionConfidence: 0.5
|
||||||
});
|
});
|
||||||
faceDetection.onResults(onResults);
|
faceDetection.onResults(onResults);
|
||||||
|
|
|
@ -203,6 +203,7 @@ class AudioToTensorCalculator : public Node {
|
||||||
std::unique_ptr<audio_dsp::QResampler<float>> resampler_;
|
std::unique_ptr<audio_dsp::QResampler<float>> resampler_;
|
||||||
Matrix sample_buffer_;
|
Matrix sample_buffer_;
|
||||||
int processed_buffer_cols_ = 0;
|
int processed_buffer_cols_ = 0;
|
||||||
|
double gain_ = 1.0;
|
||||||
|
|
||||||
// The internal state of the FFT library.
|
// The internal state of the FFT library.
|
||||||
PFFFT_Setup* fft_state_ = nullptr;
|
PFFFT_Setup* fft_state_ = nullptr;
|
||||||
|
@ -278,7 +279,9 @@ absl::Status AudioToTensorCalculator::Open(CalculatorContext* cc) {
|
||||||
padding_samples_after_ = options.padding_samples_after();
|
padding_samples_after_ = options.padding_samples_after();
|
||||||
dft_tensor_format_ = options.dft_tensor_format();
|
dft_tensor_format_ = options.dft_tensor_format();
|
||||||
flush_mode_ = options.flush_mode();
|
flush_mode_ = options.flush_mode();
|
||||||
|
if (options.has_volume_gain_db()) {
|
||||||
|
gain_ = pow(10, options.volume_gain_db() / 20.0);
|
||||||
|
}
|
||||||
RET_CHECK(kAudioSampleRateIn(cc).IsConnected() ^
|
RET_CHECK(kAudioSampleRateIn(cc).IsConnected() ^
|
||||||
!kAudioIn(cc).Header().IsEmpty())
|
!kAudioIn(cc).Header().IsEmpty())
|
||||||
<< "Must either specify the time series header of the \"AUDIO\" stream "
|
<< "Must either specify the time series header of the \"AUDIO\" stream "
|
||||||
|
@ -344,6 +347,10 @@ absl::Status AudioToTensorCalculator::Process(CalculatorContext* cc) {
|
||||||
const Matrix& input = channels_match ? input_frame
|
const Matrix& input = channels_match ? input_frame
|
||||||
// Mono mixdown.
|
// Mono mixdown.
|
||||||
: input_frame.colwise().mean();
|
: input_frame.colwise().mean();
|
||||||
|
if (gain_ != 1.0) {
|
||||||
|
return stream_mode_ ? ProcessStreamingData(cc, input * gain_)
|
||||||
|
: ProcessNonStreamingData(cc, input * gain_);
|
||||||
|
}
|
||||||
return stream_mode_ ? ProcessStreamingData(cc, input)
|
return stream_mode_ ? ProcessStreamingData(cc, input)
|
||||||
: ProcessNonStreamingData(cc, input);
|
: ProcessNonStreamingData(cc, input);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,4 +81,8 @@ message AudioToTensorCalculatorOptions {
|
||||||
WITH_DC_AND_NYQUIST = 3;
|
WITH_DC_AND_NYQUIST = 3;
|
||||||
}
|
}
|
||||||
optional DftTensorFormat dft_tensor_format = 11 [default = WITH_NYQUIST];
|
optional DftTensorFormat dft_tensor_format = 11 [default = WITH_NYQUIST];
|
||||||
|
|
||||||
|
// The volume gain, measured in dB.
|
||||||
|
// Scale the input audio amplitude by 10^(volume_gain_db/20).
|
||||||
|
optional double volume_gain_db = 12;
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,6 +167,7 @@ cc_test(
|
||||||
"//mediapipe/framework:calculator_framework",
|
"//mediapipe/framework:calculator_framework",
|
||||||
"//mediapipe/framework:calculator_runner",
|
"//mediapipe/framework:calculator_runner",
|
||||||
"//mediapipe/framework/formats:detection_cc_proto",
|
"//mediapipe/framework/formats:detection_cc_proto",
|
||||||
|
"//mediapipe/framework/formats:location_data_cc_proto",
|
||||||
"//mediapipe/framework/port:gtest_main",
|
"//mediapipe/framework/port:gtest_main",
|
||||||
"//mediapipe/framework/port:parse_text_proto",
|
"//mediapipe/framework/port:parse_text_proto",
|
||||||
],
|
],
|
||||||
|
@ -413,6 +414,7 @@ cc_library(
|
||||||
":filter_detections_calculator_cc_proto",
|
":filter_detections_calculator_cc_proto",
|
||||||
"//mediapipe/framework:calculator_framework",
|
"//mediapipe/framework:calculator_framework",
|
||||||
"//mediapipe/framework/formats:detection_cc_proto",
|
"//mediapipe/framework/formats:detection_cc_proto",
|
||||||
|
"//mediapipe/framework/formats:location_data_cc_proto",
|
||||||
"//mediapipe/framework/port:status",
|
"//mediapipe/framework/port:status",
|
||||||
"@com_google_absl//absl/memory",
|
"@com_google_absl//absl/memory",
|
||||||
],
|
],
|
||||||
|
|
|
@ -21,11 +21,13 @@
|
||||||
#include "mediapipe/calculators/util/filter_detections_calculator.pb.h"
|
#include "mediapipe/calculators/util/filter_detections_calculator.pb.h"
|
||||||
#include "mediapipe/framework/calculator_framework.h"
|
#include "mediapipe/framework/calculator_framework.h"
|
||||||
#include "mediapipe/framework/formats/detection.pb.h"
|
#include "mediapipe/framework/formats/detection.pb.h"
|
||||||
|
#include "mediapipe/framework/formats/location_data.pb.h"
|
||||||
#include "mediapipe/framework/port/status.h"
|
#include "mediapipe/framework/port/status.h"
|
||||||
|
|
||||||
namespace mediapipe {
|
namespace mediapipe {
|
||||||
|
|
||||||
const char kInputDetectionsTag[] = "INPUT_DETECTIONS";
|
const char kInputDetectionsTag[] = "INPUT_DETECTIONS";
|
||||||
|
const char kImageSizeTag[] = "IMAGE_SIZE"; // <width, height>
|
||||||
const char kOutputDetectionsTag[] = "OUTPUT_DETECTIONS";
|
const char kOutputDetectionsTag[] = "OUTPUT_DETECTIONS";
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -41,6 +43,10 @@ class FilterDetectionsCalculator : public CalculatorBase {
|
||||||
cc->Inputs().Tag(kInputDetectionsTag).Set<std::vector<Detection>>();
|
cc->Inputs().Tag(kInputDetectionsTag).Set<std::vector<Detection>>();
|
||||||
cc->Outputs().Tag(kOutputDetectionsTag).Set<std::vector<Detection>>();
|
cc->Outputs().Tag(kOutputDetectionsTag).Set<std::vector<Detection>>();
|
||||||
|
|
||||||
|
if (cc->Inputs().HasTag(kImageSizeTag)) {
|
||||||
|
cc->Inputs().Tag(kImageSizeTag).Set<std::pair<int, int>>();
|
||||||
|
}
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,22 +54,52 @@ class FilterDetectionsCalculator : public CalculatorBase {
|
||||||
cc->SetOffset(TimestampDiff(0));
|
cc->SetOffset(TimestampDiff(0));
|
||||||
options_ = cc->Options<mediapipe::FilterDetectionsCalculatorOptions>();
|
options_ = cc->Options<mediapipe::FilterDetectionsCalculatorOptions>();
|
||||||
|
|
||||||
|
if (options_.has_min_pixel_size() || options_.has_max_pixel_size()) {
|
||||||
|
RET_CHECK(cc->Inputs().HasTag(kImageSizeTag));
|
||||||
|
}
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status Process(CalculatorContext* cc) final {
|
absl::Status Process(CalculatorContext* cc) final {
|
||||||
const auto& input_detections =
|
const auto& input_detections =
|
||||||
cc->Inputs().Tag(kInputDetectionsTag).Get<std::vector<Detection>>();
|
cc->Inputs().Tag(kInputDetectionsTag).Get<std::vector<Detection>>();
|
||||||
|
|
||||||
auto output_detections = absl::make_unique<std::vector<Detection>>();
|
auto output_detections = absl::make_unique<std::vector<Detection>>();
|
||||||
|
|
||||||
|
int image_width = 0;
|
||||||
|
int image_height = 0;
|
||||||
|
if (cc->Inputs().HasTag(kImageSizeTag)) {
|
||||||
|
std::tie(image_width, image_height) =
|
||||||
|
cc->Inputs().Tag(kImageSizeTag).Get<std::pair<int, int>>();
|
||||||
|
}
|
||||||
|
|
||||||
for (const Detection& detection : input_detections) {
|
for (const Detection& detection : input_detections) {
|
||||||
|
if (options_.has_min_score()) {
|
||||||
RET_CHECK_GT(detection.score_size(), 0);
|
RET_CHECK_GT(detection.score_size(), 0);
|
||||||
// Note: only score at index 0 supported.
|
// Note: only score at index 0 supported.
|
||||||
if (detection.score(0) >= options_.min_score()) {
|
if (detection.score(0) < options_.min_score()) {
|
||||||
output_detections->push_back(detection);
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Matches rect_size in
|
||||||
|
// mediapipe/calculators/util/rect_to_render_scale_calculator.cc
|
||||||
|
const float rect_size =
|
||||||
|
std::max(detection.location_data().relative_bounding_box().width() *
|
||||||
|
image_width,
|
||||||
|
detection.location_data().relative_bounding_box().height() *
|
||||||
|
image_height);
|
||||||
|
if (options_.has_min_pixel_size()) {
|
||||||
|
if (rect_size < options_.min_pixel_size()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options_.has_max_pixel_size()) {
|
||||||
|
if (rect_size > options_.max_pixel_size()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output_detections->push_back(detection);
|
||||||
|
}
|
||||||
|
|
||||||
cc->Outputs()
|
cc->Outputs()
|
||||||
.Tag(kOutputDetectionsTag)
|
.Tag(kOutputDetectionsTag)
|
||||||
|
|
|
@ -25,4 +25,10 @@ message FilterDetectionsCalculatorOptions {
|
||||||
|
|
||||||
// Detections lower than this score get filtered out.
|
// Detections lower than this score get filtered out.
|
||||||
optional float min_score = 1;
|
optional float min_score = 1;
|
||||||
|
|
||||||
|
// Detections smaller than this size *in pixels* get filtered out.
|
||||||
|
optional float min_pixel_size = 2;
|
||||||
|
|
||||||
|
// Detections larger than this size *in pixels* get filtered out.
|
||||||
|
optional float max_pixel_size = 3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "mediapipe/framework/calculator_framework.h"
|
#include "mediapipe/framework/calculator_framework.h"
|
||||||
#include "mediapipe/framework/calculator_runner.h"
|
#include "mediapipe/framework/calculator_runner.h"
|
||||||
#include "mediapipe/framework/formats/detection.pb.h"
|
#include "mediapipe/framework/formats/detection.pb.h"
|
||||||
|
#include "mediapipe/framework/formats/location_data.pb.h"
|
||||||
#include "mediapipe/framework/port/gmock.h"
|
#include "mediapipe/framework/port/gmock.h"
|
||||||
#include "mediapipe/framework/port/gtest.h"
|
#include "mediapipe/framework/port/gtest.h"
|
||||||
#include "mediapipe/framework/port/parse_text_proto.h"
|
#include "mediapipe/framework/port/parse_text_proto.h"
|
||||||
|
@ -27,7 +28,7 @@ namespace {
|
||||||
|
|
||||||
using ::testing::ElementsAre;
|
using ::testing::ElementsAre;
|
||||||
|
|
||||||
absl::Status RunGraph(std::vector<Detection>& input_detections,
|
absl::Status RunScoreGraph(std::vector<Detection>& input_detections,
|
||||||
std::vector<Detection>* output_detections) {
|
std::vector<Detection>* output_detections) {
|
||||||
CalculatorRunner runner(R"pb(
|
CalculatorRunner runner(R"pb(
|
||||||
calculator: "FilterDetectionsCalculator"
|
calculator: "FilterDetectionsCalculator"
|
||||||
|
@ -53,7 +54,7 @@ absl::Status RunGraph(std::vector<Detection>& input_detections,
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FilterDetectionsCalculatorTest, TestFilterDetections) {
|
TEST(FilterDetectionsCalculatorTest, TestFilterDetectionsScore) {
|
||||||
std::vector<Detection> input_detections;
|
std::vector<Detection> input_detections;
|
||||||
Detection d1, d2;
|
Detection d1, d2;
|
||||||
d1.add_score(0.2);
|
d1.add_score(0.2);
|
||||||
|
@ -62,12 +63,12 @@ TEST(FilterDetectionsCalculatorTest, TestFilterDetections) {
|
||||||
input_detections.push_back(d2);
|
input_detections.push_back(d2);
|
||||||
|
|
||||||
std::vector<Detection> output_detections;
|
std::vector<Detection> output_detections;
|
||||||
MP_EXPECT_OK(RunGraph(input_detections, &output_detections));
|
MP_EXPECT_OK(RunScoreGraph(input_detections, &output_detections));
|
||||||
|
|
||||||
EXPECT_THAT(output_detections, ElementsAre(mediapipe::EqualsProto(d2)));
|
EXPECT_THAT(output_detections, ElementsAre(mediapipe::EqualsProto(d2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FilterDetectionsCalculatorTest, TestFilterDetectionsMultiple) {
|
TEST(FilterDetectionsCalculatorTest, TestFilterDetectionsScoreMultiple) {
|
||||||
std::vector<Detection> input_detections;
|
std::vector<Detection> input_detections;
|
||||||
Detection d1, d2, d3, d4;
|
Detection d1, d2, d3, d4;
|
||||||
d1.add_score(0.3);
|
d1.add_score(0.3);
|
||||||
|
@ -80,7 +81,7 @@ TEST(FilterDetectionsCalculatorTest, TestFilterDetectionsMultiple) {
|
||||||
input_detections.push_back(d4);
|
input_detections.push_back(d4);
|
||||||
|
|
||||||
std::vector<Detection> output_detections;
|
std::vector<Detection> output_detections;
|
||||||
MP_EXPECT_OK(RunGraph(input_detections, &output_detections));
|
MP_EXPECT_OK(RunScoreGraph(input_detections, &output_detections));
|
||||||
|
|
||||||
EXPECT_THAT(output_detections, ElementsAre(mediapipe::EqualsProto(d3),
|
EXPECT_THAT(output_detections, ElementsAre(mediapipe::EqualsProto(d3),
|
||||||
mediapipe::EqualsProto(d4)));
|
mediapipe::EqualsProto(d4)));
|
||||||
|
@ -90,10 +91,69 @@ TEST(FilterDetectionsCalculatorTest, TestFilterDetectionsEmpty) {
|
||||||
std::vector<Detection> input_detections;
|
std::vector<Detection> input_detections;
|
||||||
|
|
||||||
std::vector<Detection> output_detections;
|
std::vector<Detection> output_detections;
|
||||||
MP_EXPECT_OK(RunGraph(input_detections, &output_detections));
|
MP_EXPECT_OK(RunScoreGraph(input_detections, &output_detections));
|
||||||
|
|
||||||
EXPECT_EQ(output_detections.size(), 0);
|
EXPECT_EQ(output_detections.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::Status RunSizeGraph(std::vector<Detection>& input_detections,
|
||||||
|
std::pair<int, int> image_dimensions,
|
||||||
|
std::vector<Detection>* output_detections) {
|
||||||
|
CalculatorRunner runner(R"pb(
|
||||||
|
calculator: "FilterDetectionsCalculator"
|
||||||
|
input_stream: "INPUT_DETECTIONS:input_detections"
|
||||||
|
input_stream: "IMAGE_SIZE:image_dimensions"
|
||||||
|
output_stream: "OUTPUT_DETECTIONS:output_detections"
|
||||||
|
options {
|
||||||
|
[mediapipe.FilterDetectionsCalculatorOptions.ext] { min_pixel_size: 50 }
|
||||||
|
}
|
||||||
|
)pb");
|
||||||
|
|
||||||
|
const Timestamp input_timestamp = Timestamp(0);
|
||||||
|
runner.MutableInputs()
|
||||||
|
->Tag("INPUT_DETECTIONS")
|
||||||
|
.packets.push_back(MakePacket<std::vector<Detection>>(input_detections)
|
||||||
|
.At(input_timestamp));
|
||||||
|
runner.MutableInputs()
|
||||||
|
->Tag("IMAGE_SIZE")
|
||||||
|
.packets.push_back(MakePacket<std::pair<int, int>>(image_dimensions)
|
||||||
|
.At(input_timestamp));
|
||||||
|
MP_RETURN_IF_ERROR(runner.Run()) << "Calculator run failed.";
|
||||||
|
|
||||||
|
const std::vector<Packet>& output_packets =
|
||||||
|
runner.Outputs().Tag("OUTPUT_DETECTIONS").packets;
|
||||||
|
RET_CHECK_EQ(output_packets.size(), 1);
|
||||||
|
|
||||||
|
*output_detections = output_packets[0].Get<std::vector<Detection>>();
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FilterDetectionsCalculatorTest, TestFilterDetectionsMinSize) {
|
||||||
|
std::vector<Detection> input_detections;
|
||||||
|
Detection d1, d2, d3, d4, d5;
|
||||||
|
d1.mutable_location_data()->mutable_relative_bounding_box()->set_height(0.5);
|
||||||
|
d1.mutable_location_data()->mutable_relative_bounding_box()->set_width(0.49);
|
||||||
|
d2.mutable_location_data()->mutable_relative_bounding_box()->set_height(0.4);
|
||||||
|
d2.mutable_location_data()->mutable_relative_bounding_box()->set_width(0.4);
|
||||||
|
d3.mutable_location_data()->mutable_relative_bounding_box()->set_height(0.49);
|
||||||
|
d3.mutable_location_data()->mutable_relative_bounding_box()->set_width(0.5);
|
||||||
|
d4.mutable_location_data()->mutable_relative_bounding_box()->set_height(0.49);
|
||||||
|
d4.mutable_location_data()->mutable_relative_bounding_box()->set_width(0.49);
|
||||||
|
d5.mutable_location_data()->mutable_relative_bounding_box()->set_height(0.5);
|
||||||
|
d5.mutable_location_data()->mutable_relative_bounding_box()->set_width(0.5);
|
||||||
|
input_detections.push_back(d1);
|
||||||
|
input_detections.push_back(d2);
|
||||||
|
input_detections.push_back(d3);
|
||||||
|
input_detections.push_back(d4);
|
||||||
|
input_detections.push_back(d5);
|
||||||
|
|
||||||
|
std::vector<Detection> output_detections;
|
||||||
|
MP_EXPECT_OK(RunSizeGraph(input_detections, {100, 100}, &output_detections));
|
||||||
|
|
||||||
|
EXPECT_THAT(output_detections, ElementsAre(mediapipe::EqualsProto(d1),
|
||||||
|
mediapipe::EqualsProto(d3),
|
||||||
|
mediapipe::EqualsProto(d5)));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace mediapipe
|
} // namespace mediapipe
|
||||||
|
|
|
@ -53,14 +53,10 @@
|
||||||
#include "mediapipe/framework/port/status.h"
|
#include "mediapipe/framework/port/status.h"
|
||||||
#include "mediapipe/framework/scheduler.h"
|
#include "mediapipe/framework/scheduler.h"
|
||||||
#include "mediapipe/framework/thread_pool_executor.pb.h"
|
#include "mediapipe/framework/thread_pool_executor.pb.h"
|
||||||
|
#include "mediapipe/gpu/gpu_service.h"
|
||||||
|
|
||||||
namespace mediapipe {
|
namespace mediapipe {
|
||||||
|
|
||||||
#if !MEDIAPIPE_DISABLE_GPU
|
|
||||||
class GpuResources;
|
|
||||||
struct GpuSharedData;
|
|
||||||
#endif // !MEDIAPIPE_DISABLE_GPU
|
|
||||||
|
|
||||||
typedef absl::StatusOr<OutputStreamPoller> StatusOrPoller;
|
typedef absl::StatusOr<OutputStreamPoller> StatusOrPoller;
|
||||||
|
|
||||||
// The class representing a DAG of calculator nodes.
|
// The class representing a DAG of calculator nodes.
|
||||||
|
|
|
@ -251,13 +251,8 @@ TEST_F(TextClassifierTest, BertLongPositive) {
|
||||||
TextClassifierResult expected;
|
TextClassifierResult expected;
|
||||||
std::vector<Category> categories;
|
std::vector<Category> categories;
|
||||||
|
|
||||||
// Predicted scores are slightly different across platforms.
|
// Predicted scores are slightly different on Windows.
|
||||||
#ifdef __APPLE__
|
#ifdef _WIN32
|
||||||
categories.push_back(
|
|
||||||
{/*index=*/1, /*score=*/0.974181, /*category_name=*/"positive"});
|
|
||||||
categories.push_back(
|
|
||||||
{/*index=*/0, /*score=*/0.025819, /*category_name=*/"negative"});
|
|
||||||
#elif defined _WIN32
|
|
||||||
categories.push_back(
|
categories.push_back(
|
||||||
{/*index=*/1, /*score=*/0.976686, /*category_name=*/"positive"});
|
{/*index=*/1, /*score=*/0.976686, /*category_name=*/"positive"});
|
||||||
categories.push_back(
|
categories.push_back(
|
||||||
|
@ -267,7 +262,7 @@ TEST_F(TextClassifierTest, BertLongPositive) {
|
||||||
{/*index=*/1, /*score=*/0.985889, /*category_name=*/"positive"});
|
{/*index=*/1, /*score=*/0.985889, /*category_name=*/"positive"});
|
||||||
categories.push_back(
|
categories.push_back(
|
||||||
{/*index=*/0, /*score=*/0.014112, /*category_name=*/"negative"});
|
{/*index=*/0, /*score=*/0.014112, /*category_name=*/"negative"});
|
||||||
#endif // __APPLE__
|
#endif // _WIN32
|
||||||
|
|
||||||
expected.classifications.emplace_back(
|
expected.classifications.emplace_back(
|
||||||
Classifications{/*categories=*/categories,
|
Classifications{/*categories=*/categories,
|
||||||
|
|
|
@ -84,8 +84,8 @@ TEST_P(HandednessToMatrixCalculatorTest, OutputsCorrectResult) {
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
HandednessToMatrixCalculatorTests, HandednessToMatrixCalculatorTest,
|
HandednessToMatrixCalculatorTests, HandednessToMatrixCalculatorTest,
|
||||||
testing::ValuesIn<HandednessToMatrixCalculatorTestCase>(
|
testing::ValuesIn<HandednessToMatrixCalculatorTestCase>(
|
||||||
{{.test_name = "TestWithRightHand", .handedness = 0.01f},
|
{{/* test_name= */ "TestWithRightHand", /* handedness= */ 0.01f},
|
||||||
{.test_name = "TestWithLeftHand", .handedness = 0.99f}}),
|
{/* test_name= */ "TestWithLeftHand", /* handedness= */ 0.99f}}),
|
||||||
[](const testing::TestParamInfo<
|
[](const testing::TestParamInfo<
|
||||||
HandednessToMatrixCalculatorTest::ParamType>& info) {
|
HandednessToMatrixCalculatorTest::ParamType>& info) {
|
||||||
return info.param.test_name;
|
return info.param.test_name;
|
||||||
|
|
33
mediapipe/tasks/ios/components/utils/BUILD
Normal file
33
mediapipe/tasks/ios/components/utils/BUILD
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
package(default_visibility = ["//mediapipe/tasks:internal"])
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
objc_library(
|
||||||
|
name = "MPPCosineSimilarity",
|
||||||
|
srcs = ["sources/MPPCosineSimilarity.mm"],
|
||||||
|
hdrs = ["sources/MPPCosineSimilarity.h"],
|
||||||
|
copts = [
|
||||||
|
"-ObjC++",
|
||||||
|
"-std=c++17",
|
||||||
|
"-x objective-c++",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//mediapipe/tasks/ios/common:MPPCommon",
|
||||||
|
"//mediapipe/tasks/ios/common/utils:MPPCommonUtils",
|
||||||
|
"//mediapipe/tasks/ios/components/containers:MPPEmbedding",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,48 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "mediapipe/tasks/ios/components/containers/sources/MPPEmbedding.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/** Utility class for computing cosine similarity between `MPPEmbedding` objects. */
|
||||||
|
NS_SWIFT_NAME(CosineSimilarity)
|
||||||
|
|
||||||
|
@interface MPPCosineSimilarity : NSObject
|
||||||
|
|
||||||
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
+ (instancetype)new NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
/** Utility function to compute[cosine similarity](https://en.wikipedia.org/wiki/Cosine_similarity)
|
||||||
|
* between two `MPPEmbedding` objects.
|
||||||
|
*
|
||||||
|
* @param embedding1 One of the two `MPPEmbedding`s between whom cosine similarity is to be
|
||||||
|
* computed.
|
||||||
|
* @param embedding2 One of the two `MPPEmbedding`s between whom cosine similarity is to be
|
||||||
|
* computed.
|
||||||
|
* @param error An optional error parameter populated when there is an error in calculating cosine
|
||||||
|
* similarity between two embeddings.
|
||||||
|
*
|
||||||
|
* @return An `NSNumber` which holds the cosine similarity of type `double`.
|
||||||
|
*/
|
||||||
|
+ (nullable NSNumber *)computeBetweenEmbedding1:(MPPEmbedding *)embedding1
|
||||||
|
andEmbedding2:(MPPEmbedding *)embedding2
|
||||||
|
error:(NSError **)error;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,88 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#import "mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#import "mediapipe/tasks/ios/common/sources/MPPCommon.h"
|
||||||
|
#import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h"
|
||||||
|
|
||||||
|
@implementation MPPCosineSimilarity
|
||||||
|
|
||||||
|
+ (nullable NSNumber *)computeBetweenVector1:(NSArray<NSNumber *> *)u
|
||||||
|
andVector2:(NSArray<NSNumber *> *)v
|
||||||
|
isFloat:(BOOL)isFloat
|
||||||
|
error:(NSError **)error {
|
||||||
|
if (u.count != v.count) {
|
||||||
|
[MPPCommonUtils
|
||||||
|
createCustomError:error
|
||||||
|
withCode:MPPTasksErrorCodeInvalidArgumentError
|
||||||
|
description:[NSString stringWithFormat:@"Cannot compute cosine similarity between "
|
||||||
|
@"embeddings of different sizes (%lu vs %lu",
|
||||||
|
static_cast<u_long>(u.count),
|
||||||
|
static_cast<u_long>(v.count)]];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
__block double dotProduct = 0.0;
|
||||||
|
__block double normU = 0.0;
|
||||||
|
__block double normV = 0.0;
|
||||||
|
|
||||||
|
[u enumerateObjectsUsingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
|
||||||
|
double uVal = 0.0;
|
||||||
|
double vVal = 0.0;
|
||||||
|
|
||||||
|
if (isFloat) {
|
||||||
|
uVal = num.floatValue;
|
||||||
|
vVal = v[idx].floatValue;
|
||||||
|
} else {
|
||||||
|
uVal = num.charValue;
|
||||||
|
vVal = v[idx].charValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dotProduct += uVal * vVal;
|
||||||
|
normU += uVal * uVal;
|
||||||
|
normV += vVal * vVal;
|
||||||
|
}];
|
||||||
|
|
||||||
|
return [NSNumber numberWithDouble:dotProduct / sqrt(normU * normV)];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (nullable NSNumber *)computeBetweenEmbedding1:(MPPEmbedding *)embedding1
|
||||||
|
andEmbedding2:(MPPEmbedding *)embedding2
|
||||||
|
error:(NSError **)error {
|
||||||
|
if (embedding1.floatEmbedding && embedding2.floatEmbedding) {
|
||||||
|
return [MPPCosineSimilarity computeBetweenVector1:embedding1.floatEmbedding
|
||||||
|
andVector2:embedding2.floatEmbedding
|
||||||
|
isFloat:YES
|
||||||
|
error:error];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (embedding1.quantizedEmbedding && embedding2.quantizedEmbedding) {
|
||||||
|
return [MPPCosineSimilarity computeBetweenVector1:embedding1.quantizedEmbedding
|
||||||
|
andVector2:embedding2.quantizedEmbedding
|
||||||
|
isFloat:NO
|
||||||
|
error:error];
|
||||||
|
}
|
||||||
|
|
||||||
|
[MPPCommonUtils
|
||||||
|
createCustomError:error
|
||||||
|
withCode:MPPTasksErrorCodeInvalidArgumentError
|
||||||
|
description:
|
||||||
|
@"Cannot compute cosine similarity between quantized and float embeddings."];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
80
mediapipe/tasks/ios/test/text/text_embedder/BUILD
Normal file
80
mediapipe/tasks/ios/test/text/text_embedder/BUILD
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
load(
|
||||||
|
"@build_bazel_rules_apple//apple:ios.bzl",
|
||||||
|
"ios_unit_test",
|
||||||
|
)
|
||||||
|
load(
|
||||||
|
"@build_bazel_rules_swift//swift:swift.bzl",
|
||||||
|
"swift_library",
|
||||||
|
)
|
||||||
|
load(
|
||||||
|
"//mediapipe/tasks:ios/ios.bzl",
|
||||||
|
"MPP_TASK_MINIMUM_OS_VERSION",
|
||||||
|
)
|
||||||
|
load(
|
||||||
|
"@org_tensorflow//tensorflow/lite:special_rules.bzl",
|
||||||
|
"tflite_ios_lab_runner",
|
||||||
|
)
|
||||||
|
|
||||||
|
package(default_visibility = ["//mediapipe/tasks:internal"])
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
# Default tags for filtering iOS targets. Targets are restricted to Apple platforms.
|
||||||
|
TFL_DEFAULT_TAGS = [
|
||||||
|
"apple",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Following sanitizer tests are not supported by iOS test targets.
|
||||||
|
TFL_DISABLED_SANITIZER_TAGS = [
|
||||||
|
"noasan",
|
||||||
|
"nomsan",
|
||||||
|
"notsan",
|
||||||
|
]
|
||||||
|
|
||||||
|
objc_library(
|
||||||
|
name = "MPPTextEmbedderObjcTestLibrary",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["MPPTextEmbedderTests.m"],
|
||||||
|
data = [
|
||||||
|
"//mediapipe/tasks/testdata/text:mobilebert_embedding_model",
|
||||||
|
"//mediapipe/tasks/testdata/text:regex_embedding_with_metadata",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//mediapipe/tasks/ios/common:MPPCommon",
|
||||||
|
"//mediapipe/tasks/ios/text/text_embedder:MPPTextEmbedder",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
ios_unit_test(
|
||||||
|
name = "MPPTextEmbedderObjcTest",
|
||||||
|
minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION,
|
||||||
|
runner = tflite_ios_lab_runner("IOS_LATEST"),
|
||||||
|
deps = [
|
||||||
|
":MPPTextEmbedderObjcTestLibrary",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
swift_library(
|
||||||
|
name = "MPPTextEmbedderSwiftTestLibrary",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["TextEmbedderTests.swift"],
|
||||||
|
data = [
|
||||||
|
"//mediapipe/tasks/testdata/text:mobilebert_embedding_model",
|
||||||
|
"//mediapipe/tasks/testdata/text:regex_embedding_with_metadata",
|
||||||
|
],
|
||||||
|
tags = TFL_DEFAULT_TAGS,
|
||||||
|
deps = [
|
||||||
|
"//mediapipe/tasks/ios/common:MPPCommon",
|
||||||
|
"//mediapipe/tasks/ios/text/text_embedder:MPPTextEmbedder",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
ios_unit_test(
|
||||||
|
name = "MPPTextEmbedderSwiftTest",
|
||||||
|
minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION,
|
||||||
|
runner = tflite_ios_lab_runner("IOS_LATEST"),
|
||||||
|
tags = TFL_DEFAULT_TAGS + TFL_DISABLED_SANITIZER_TAGS,
|
||||||
|
deps = [
|
||||||
|
":MPPTextEmbedderSwiftTestLibrary",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,246 @@
|
||||||
|
// Copyright 2023 The MediaPipe Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#import <XCTest/XCTest.h>
|
||||||
|
|
||||||
|
#import "mediapipe/tasks/ios/common/sources/MPPCommon.h"
|
||||||
|
#import "mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedder.h"
|
||||||
|
|
||||||
|
static NSString *const kBertTextEmbedderModelName = @"mobilebert_embedding_with_metadata";
|
||||||
|
static NSString *const kRegexTextEmbedderModelName = @"regex_one_embedding_with_metadata";
|
||||||
|
static NSString *const kText1 = @"it's a charming and often affecting journey";
|
||||||
|
static NSString *const kText2 = @"what a great and fantastic trip";
|
||||||
|
static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks";
|
||||||
|
static const float kFloatDiffTolerance = 1e-4;
|
||||||
|
static const float kSimilarityDiffTolerance = 1e-4;
|
||||||
|
|
||||||
|
#define AssertEqualErrors(error, expectedError) \
|
||||||
|
XCTAssertNotNil(error); \
|
||||||
|
XCTAssertEqualObjects(error.domain, expectedError.domain); \
|
||||||
|
XCTAssertEqual(error.code, expectedError.code); \
|
||||||
|
XCTAssertNotEqual( \
|
||||||
|
[error.localizedDescription rangeOfString:expectedError.localizedDescription].location, \
|
||||||
|
NSNotFound)
|
||||||
|
|
||||||
|
#define AssertTextEmbedderResultHasOneEmbedding(textEmbedderResult) \
|
||||||
|
XCTAssertNotNil(textEmbedderResult); \
|
||||||
|
XCTAssertNotNil(textEmbedderResult.embeddingResult); \
|
||||||
|
XCTAssertEqual(textEmbedderResult.embeddingResult.embeddings.count, 1);
|
||||||
|
|
||||||
|
#define AssertEmbeddingType(embedding, quantized) \
|
||||||
|
if (quantized) { \
|
||||||
|
XCTAssertNil(embedding.floatEmbedding); \
|
||||||
|
XCTAssertNotNil(embedding.quantizedEmbedding); \
|
||||||
|
} else { \
|
||||||
|
XCTAssertNotNil(embedding.floatEmbedding); \
|
||||||
|
XCTAssertNil(embedding.quantizedEmbedding); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define AssertEmbeddingHasExpectedValues(embedding, expectedLength, expectedFirstValue, quantize) \
|
||||||
|
XCTAssertEqual(embedding.count, expectedLength); \
|
||||||
|
if (quantize) { \
|
||||||
|
XCTAssertEqual(embedding[0].charValue, expectedFirstValue); \
|
||||||
|
} else { \
|
||||||
|
XCTAssertEqualWithAccuracy(embedding[0].floatValue, expectedFirstValue, kFloatDiffTolerance); \
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface MPPTextEmbedderTests : XCTestCase
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPPTextEmbedderTests
|
||||||
|
|
||||||
|
- (NSString *)filePathWithName:(NSString *)fileName extension:(NSString *)extension {
|
||||||
|
return [[NSBundle bundleForClass:self.class] pathForResource:fileName
|
||||||
|
ofType:extension];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPPTextEmbedder *)textEmbedderFromModelFileWithName:(NSString *)modelName {
|
||||||
|
NSString *modelPath = [self filePathWithName:modelName extension:@"tflite"];
|
||||||
|
|
||||||
|
NSError *error = nil;
|
||||||
|
MPPTextEmbedder *textEmbedder = [[MPPTextEmbedder alloc] initWithModelPath:modelPath
|
||||||
|
error:&error];
|
||||||
|
|
||||||
|
XCTAssertNotNil(textEmbedder);
|
||||||
|
|
||||||
|
return textEmbedder;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPPTextEmbedderOptions *)textEmbedderOptionsWithModelName:(NSString *)modelName {
|
||||||
|
NSString *modelPath = [self filePathWithName:modelName extension:@"tflite"];
|
||||||
|
MPPTextEmbedderOptions *textEmbedderOptions = [[MPPTextEmbedderOptions alloc] init];
|
||||||
|
textEmbedderOptions.baseOptions.modelAssetPath = modelPath;
|
||||||
|
|
||||||
|
return textEmbedderOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPPEmbedding *)assertFloatEmbeddingResultsOfEmbedText:(NSString *)text
|
||||||
|
usingTextEmbedder:(MPPTextEmbedder *)textEmbedder
|
||||||
|
hasCount:(NSUInteger)embeddingCount
|
||||||
|
firstValue:(float)firstValue {
|
||||||
|
MPPTextEmbedderResult *embedderResult = [textEmbedder embedText:text error:nil];
|
||||||
|
AssertTextEmbedderResultHasOneEmbedding(embedderResult);
|
||||||
|
|
||||||
|
AssertEmbeddingType(embedderResult.embeddingResult.embeddings[0], // embedding
|
||||||
|
NO // quantized
|
||||||
|
);
|
||||||
|
|
||||||
|
AssertEmbeddingHasExpectedValues(
|
||||||
|
embedderResult.embeddingResult.embeddings[0].floatEmbedding, // embedding
|
||||||
|
embeddingCount, // expectedLength
|
||||||
|
firstValue, // expectedFirstValue
|
||||||
|
NO // quantize
|
||||||
|
);
|
||||||
|
|
||||||
|
return embedderResult.embeddingResult.embeddings[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPPEmbedding *)assertQuantizedEmbeddingResultsOfEmbedText:(NSString *)text
|
||||||
|
usingTextEmbedder:(MPPTextEmbedder *)textEmbedder
|
||||||
|
hasCount:(NSUInteger)embeddingCount
|
||||||
|
firstValue:(char)firstValue {
|
||||||
|
MPPTextEmbedderResult *embedderResult = [textEmbedder embedText:text error:nil];
|
||||||
|
AssertTextEmbedderResultHasOneEmbedding(embedderResult);
|
||||||
|
|
||||||
|
AssertEmbeddingType(embedderResult.embeddingResult.embeddings[0], // embedding
|
||||||
|
YES // quantized
|
||||||
|
);
|
||||||
|
|
||||||
|
AssertEmbeddingHasExpectedValues(
|
||||||
|
embedderResult.embeddingResult.embeddings[0].quantizedEmbedding, // embedding
|
||||||
|
embeddingCount, // expectedLength
|
||||||
|
firstValue, // expectedFirstValue
|
||||||
|
YES // quantize
|
||||||
|
);
|
||||||
|
|
||||||
|
return embedderResult.embeddingResult.embeddings[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testCreateTextEmbedderFailsWithMissingModelPath {
|
||||||
|
NSString *modelPath = [self filePathWithName:@"" extension:@""];
|
||||||
|
|
||||||
|
NSError *error = nil;
|
||||||
|
MPPTextEmbedder *textEmbedder = [[MPPTextEmbedder alloc] initWithModelPath:modelPath
|
||||||
|
error:&error];
|
||||||
|
XCTAssertNil(textEmbedder);
|
||||||
|
|
||||||
|
NSError *expectedError = [NSError
|
||||||
|
errorWithDomain:kExpectedErrorDomain
|
||||||
|
code:MPPTasksErrorCodeInvalidArgumentError
|
||||||
|
userInfo:@{
|
||||||
|
NSLocalizedDescriptionKey :
|
||||||
|
@"INVALID_ARGUMENT: ExternalFile must specify at least one of 'file_content', "
|
||||||
|
@"'file_name', 'file_pointer_meta' or 'file_descriptor_meta'."
|
||||||
|
}];
|
||||||
|
AssertEqualErrors(error, // error
|
||||||
|
expectedError // expectedError
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testEmbedWithBertSucceeds {
|
||||||
|
MPPTextEmbedder *textEmbedder =
|
||||||
|
[self textEmbedderFromModelFileWithName:kBertTextEmbedderModelName];
|
||||||
|
|
||||||
|
MPPEmbedding *embedding1 =
|
||||||
|
[self assertFloatEmbeddingResultsOfEmbedText:kText1
|
||||||
|
usingTextEmbedder:textEmbedder
|
||||||
|
hasCount:512
|
||||||
|
firstValue:21.214869f];
|
||||||
|
|
||||||
|
MPPEmbedding *embedding2 = [self assertFloatEmbeddingResultsOfEmbedText:kText2
|
||||||
|
usingTextEmbedder:textEmbedder
|
||||||
|
hasCount:512
|
||||||
|
firstValue:22.626251f];
|
||||||
|
NSNumber *cosineSimilarity = [MPPTextEmbedder cosineSimilarityBetweenEmbedding1:embedding1
|
||||||
|
andEmbedding2:embedding2
|
||||||
|
error:nil];
|
||||||
|
|
||||||
|
XCTAssertEqualWithAccuracy(cosineSimilarity.doubleValue, 0.971417490189,
|
||||||
|
kSimilarityDiffTolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testEmbedWithRegexSucceeds {
|
||||||
|
MPPTextEmbedder *textEmbedder =
|
||||||
|
[self textEmbedderFromModelFileWithName:kRegexTextEmbedderModelName];
|
||||||
|
|
||||||
|
MPPEmbedding *embedding1 = [self assertFloatEmbeddingResultsOfEmbedText:kText1
|
||||||
|
usingTextEmbedder:textEmbedder
|
||||||
|
hasCount:16
|
||||||
|
firstValue:0.030935612f];
|
||||||
|
|
||||||
|
MPPEmbedding *embedding2 = [self assertFloatEmbeddingResultsOfEmbedText:kText2
|
||||||
|
usingTextEmbedder:textEmbedder
|
||||||
|
hasCount:16
|
||||||
|
firstValue:0.0312863f];
|
||||||
|
|
||||||
|
NSNumber *cosineSimilarity = [MPPTextEmbedder cosineSimilarityBetweenEmbedding1:embedding1
|
||||||
|
andEmbedding2:embedding2
|
||||||
|
error:nil];
|
||||||
|
|
||||||
|
XCTAssertEqualWithAccuracy(cosineSimilarity.doubleValue, 0.999937f, kSimilarityDiffTolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testEmbedWithBertAndDifferentThemesSucceeds {
|
||||||
|
MPPTextEmbedder *textEmbedder =
|
||||||
|
[self textEmbedderFromModelFileWithName:kBertTextEmbedderModelName];
|
||||||
|
|
||||||
|
MPPEmbedding *embedding1 =
|
||||||
|
[self assertFloatEmbeddingResultsOfEmbedText:
|
||||||
|
@"When you go to this restaurant, they hold the pancake upside-down before they "
|
||||||
|
@"hand it to you. It's a great gimmick."
|
||||||
|
usingTextEmbedder:textEmbedder
|
||||||
|
hasCount:512
|
||||||
|
firstValue:43.1663];
|
||||||
|
|
||||||
|
MPPEmbedding *embedding2 =
|
||||||
|
[self assertFloatEmbeddingResultsOfEmbedText:
|
||||||
|
@"Let's make a plan to steal the declaration of independence."
|
||||||
|
usingTextEmbedder:textEmbedder
|
||||||
|
hasCount:512
|
||||||
|
firstValue:48.0898];
|
||||||
|
|
||||||
|
NSNumber *cosineSimilarity = [MPPTextEmbedder cosineSimilarityBetweenEmbedding1:embedding1
|
||||||
|
andEmbedding2:embedding2
|
||||||
|
error:nil];
|
||||||
|
|
||||||
|
// TODO: The similarity should likely be lower
|
||||||
|
XCTAssertEqualWithAccuracy(cosineSimilarity.doubleValue, 0.98151f, kSimilarityDiffTolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testEmbedWithQuantizeSucceeds {
|
||||||
|
MPPTextEmbedderOptions *options =
|
||||||
|
[self textEmbedderOptionsWithModelName:kBertTextEmbedderModelName];
|
||||||
|
options.quantize = YES;
|
||||||
|
|
||||||
|
MPPTextEmbedder *textEmbedder = [[MPPTextEmbedder alloc] initWithOptions:options error:nil];
|
||||||
|
XCTAssertNotNil(textEmbedder);
|
||||||
|
|
||||||
|
MPPEmbedding *embedding1 = [self
|
||||||
|
assertQuantizedEmbeddingResultsOfEmbedText:@"it's a charming and often affecting journey"
|
||||||
|
usingTextEmbedder:textEmbedder
|
||||||
|
hasCount:512
|
||||||
|
firstValue:127];
|
||||||
|
|
||||||
|
MPPEmbedding *embedding2 =
|
||||||
|
[self assertQuantizedEmbeddingResultsOfEmbedText:@"what a great and fantastic trip"
|
||||||
|
usingTextEmbedder:textEmbedder
|
||||||
|
hasCount:512
|
||||||
|
firstValue:127];
|
||||||
|
NSNumber *cosineSimilarity = [MPPTextEmbedder cosineSimilarityBetweenEmbedding1:embedding1
|
||||||
|
andEmbedding2:embedding2
|
||||||
|
error:nil];
|
||||||
|
XCTAssertEqualWithAccuracy(cosineSimilarity.doubleValue, 0.88164f, kSimilarityDiffTolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,121 @@
|
||||||
|
// Copyright 2023 The MediaPipe Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import MPPCommon
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable import MPPTextEmbedder
|
||||||
|
|
||||||
|
/// These tests are only for validating the Swift function signatures of the TextEmbedder.
|
||||||
|
/// Objective C tests of the TextEmbedder provide more coverage with unit tests for
|
||||||
|
/// different models and text embedder options. They can be found here:
|
||||||
|
/// /mediapipe/tasks/ios/test/text/text_embedder/MPPTextEmbedderTests.m
|
||||||
|
|
||||||
|
class TextEmbedderTests: XCTestCase {
|
||||||
|
|
||||||
|
static let bundle = Bundle(for: TextEmbedderTests.self)
|
||||||
|
|
||||||
|
static let bertModelPath = bundle.path(
|
||||||
|
forResource: "mobilebert_embedding_with_metadata",
|
||||||
|
ofType: "tflite")
|
||||||
|
|
||||||
|
static let text1 = "it's a charming and often affecting journey"
|
||||||
|
|
||||||
|
static let text2 = "what a great and fantastic trip"
|
||||||
|
|
||||||
|
static let floatDiffTolerance: Float = 1e-4
|
||||||
|
|
||||||
|
static let doubleDiffTolerance: Double = 1e-4
|
||||||
|
|
||||||
|
func assertEqualErrorDescriptions(
|
||||||
|
_ error: Error, expectedLocalizedDescription: String
|
||||||
|
) {
|
||||||
|
XCTAssertEqual(
|
||||||
|
error.localizedDescription,
|
||||||
|
expectedLocalizedDescription)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertTextEmbedderResultHasOneEmbedding(
|
||||||
|
_ textEmbedderResult: TextEmbedderResult
|
||||||
|
) {
|
||||||
|
XCTAssertEqual(textEmbedderResult.embeddingResult.embeddings.count, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertEmbeddingIsFloat(
|
||||||
|
_ embedding: Embedding
|
||||||
|
) {
|
||||||
|
XCTAssertNil(embedding.quantizedEmbedding)
|
||||||
|
XCTAssertNotNil(embedding.floatEmbedding)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertEmbedding(
|
||||||
|
_ floatEmbedding: [NSNumber],
|
||||||
|
hasCount embeddingCount: Int,
|
||||||
|
hasFirstValue firstValue: Float
|
||||||
|
) {
|
||||||
|
XCTAssertEqual(floatEmbedding.count, embeddingCount)
|
||||||
|
XCTAssertEqual(
|
||||||
|
floatEmbedding[0].floatValue,
|
||||||
|
firstValue,
|
||||||
|
accuracy:
|
||||||
|
TextEmbedderTests.floatDiffTolerance)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertFloatEmbeddingResultsForEmbed(
|
||||||
|
text: String,
|
||||||
|
using textEmbedder: TextEmbedder,
|
||||||
|
hasCount embeddingCount: Int,
|
||||||
|
hasFirstValue firstValue: Float
|
||||||
|
) throws -> Embedding {
|
||||||
|
let textEmbedderResult =
|
||||||
|
try XCTUnwrap(
|
||||||
|
textEmbedder.embed(text: text))
|
||||||
|
assertTextEmbedderResultHasOneEmbedding(textEmbedderResult)
|
||||||
|
assertEmbeddingIsFloat(textEmbedderResult.embeddingResult.embeddings[0])
|
||||||
|
assertEmbedding(
|
||||||
|
textEmbedderResult.embeddingResult.embeddings[0].floatEmbedding!,
|
||||||
|
hasCount: embeddingCount,
|
||||||
|
hasFirstValue: firstValue)
|
||||||
|
|
||||||
|
return textEmbedderResult.embeddingResult.embeddings[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func testEmbedWithBertSucceeds() throws {
|
||||||
|
|
||||||
|
let modelPath = try XCTUnwrap(TextEmbedderTests.bertModelPath)
|
||||||
|
let textEmbedder = try XCTUnwrap(TextEmbedder(modelPath: modelPath))
|
||||||
|
|
||||||
|
let embedding1 = try assertFloatEmbeddingResultsForEmbed(
|
||||||
|
text: TextEmbedderTests.text1,
|
||||||
|
using: textEmbedder,
|
||||||
|
hasCount: 512,
|
||||||
|
hasFirstValue: 21.214869)
|
||||||
|
|
||||||
|
let embedding2 = try assertFloatEmbeddingResultsForEmbed(
|
||||||
|
text: TextEmbedderTests.text2,
|
||||||
|
using: textEmbedder,
|
||||||
|
hasCount: 512,
|
||||||
|
hasFirstValue: 22.626251)
|
||||||
|
|
||||||
|
let cosineSimilarity = try XCTUnwrap(
|
||||||
|
TextEmbedder.cosineSimilarity(
|
||||||
|
embedding1: embedding1,
|
||||||
|
embedding2: embedding2))
|
||||||
|
|
||||||
|
XCTAssertEqual(
|
||||||
|
cosineSimilarity.doubleValue,
|
||||||
|
0.97141,
|
||||||
|
accuracy: TextEmbedderTests.doubleDiffTolerance)
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,6 +49,7 @@ objc_library(
|
||||||
"//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph",
|
"//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph",
|
||||||
"//mediapipe/tasks/ios/common/utils:MPPCommonUtils",
|
"//mediapipe/tasks/ios/common/utils:MPPCommonUtils",
|
||||||
"//mediapipe/tasks/ios/common/utils:NSStringHelpers",
|
"//mediapipe/tasks/ios/common/utils:NSStringHelpers",
|
||||||
|
"//mediapipe/tasks/ios/components/utils:MPPCosineSimilarity",
|
||||||
"//mediapipe/tasks/ios/core:MPPTaskInfo",
|
"//mediapipe/tasks/ios/core:MPPTaskInfo",
|
||||||
"//mediapipe/tasks/ios/core:MPPTaskOptions",
|
"//mediapipe/tasks/ios/core:MPPTaskOptions",
|
||||||
"//mediapipe/tasks/ios/core:MPPTextPacketCreator",
|
"//mediapipe/tasks/ios/core:MPPTextPacketCreator",
|
||||||
|
|
|
@ -86,6 +86,24 @@ NS_SWIFT_NAME(TextEmbedder)
|
||||||
|
|
||||||
- (instancetype)init NS_UNAVAILABLE;
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility function to compute[cosine similarity](https://en.wikipedia.org/wiki/Cosine_similarity)
|
||||||
|
* between two `MPPEmbedding` objects.
|
||||||
|
*
|
||||||
|
* @param embedding1 One of the two `MPPEmbedding`s between whom cosine similarity is to be
|
||||||
|
* computed.
|
||||||
|
* @param embedding2 One of the two `MPPEmbedding`s between whom cosine similarity is to be
|
||||||
|
* computed.
|
||||||
|
* @param error An optional error parameter populated when there is an error in calculating cosine
|
||||||
|
* similarity between two embeddings.
|
||||||
|
*
|
||||||
|
* @return An `NSNumber` which holds the cosine similarity of type `double`.
|
||||||
|
*/
|
||||||
|
+ (nullable NSNumber *)cosineSimilarityBetweenEmbedding1:(MPPEmbedding *)embedding1
|
||||||
|
andEmbedding2:(MPPEmbedding *)embedding2
|
||||||
|
error:(NSError **)error
|
||||||
|
NS_SWIFT_NAME(cosineSimilarity(embedding1:embedding2:));
|
||||||
|
|
||||||
+ (instancetype)new NS_UNAVAILABLE;
|
+ (instancetype)new NS_UNAVAILABLE;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h"
|
#import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h"
|
||||||
#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h"
|
#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h"
|
||||||
|
#import "mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.h"
|
||||||
#import "mediapipe/tasks/ios/core/sources/MPPTaskInfo.h"
|
#import "mediapipe/tasks/ios/core/sources/MPPTaskInfo.h"
|
||||||
#import "mediapipe/tasks/ios/core/sources/MPPTextPacketCreator.h"
|
#import "mediapipe/tasks/ios/core/sources/MPPTextPacketCreator.h"
|
||||||
#import "mediapipe/tasks/ios/text/core/sources/MPPTextTaskRunner.h"
|
#import "mediapipe/tasks/ios/text/core/sources/MPPTextTaskRunner.h"
|
||||||
|
@ -93,4 +94,12 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.text.text_embedder.Tex
|
||||||
.value()[kEmbeddingsOutStreamName.cppString]];
|
.value()[kEmbeddingsOutStreamName.cppString]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (nullable NSNumber *)cosineSimilarityBetweenEmbedding1:(MPPEmbedding *)embedding1
|
||||||
|
andEmbedding2:(MPPEmbedding *)embedding2
|
||||||
|
error:(NSError **)error {
|
||||||
|
return [MPPCosineSimilarity computeBetweenEmbedding1:embedding1
|
||||||
|
andEmbedding2:embedding2
|
||||||
|
error:error];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -41,10 +41,10 @@ NS_SWIFT_NAME(MPImage)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The display orientation of the image. If `imageSourceType` is `MPPImageSourceTypeImage`, the
|
* The display orientation of the image. If `imageSourceType` is `MPPImageSourceTypeImage`, the
|
||||||
* default value is `image.imageOrientation`; otherwise the default value is `UIImageOrientationUp`.
|
* default value is `image.imageOrientation`; otherwise the default value is
|
||||||
* If the `MPPImage` is being used as input for any MediaPipe vision tasks and is set to any
|
* `UIImageOrientationUp`. If the `MPPImage` is being used as input for any MediaPipe vision tasks
|
||||||
* orientation other than `UIImageOrientationUp`, inference will be performed on a rotated copy of
|
* and is set to any orientation other than `UIImageOrientationUp`, inference will be performed on
|
||||||
* the image according to the orientation.
|
* a rotated copy of the image according to the orientation.
|
||||||
*/
|
*/
|
||||||
@property(nonatomic, readonly) UIImageOrientation orientation;
|
@property(nonatomic, readonly) UIImageOrientation orientation;
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ NS_SWIFT_NAME(MPImage)
|
||||||
/**
|
/**
|
||||||
* Initializes an `MPPImage` object with the given `UIImage`.
|
* Initializes an `MPPImage` object with the given `UIImage`.
|
||||||
* The orientation of the newly created `MPPImage` will be `UIImageOrientationUp`.
|
* The orientation of the newly created `MPPImage` will be `UIImageOrientationUp`.
|
||||||
* Hence, if this image is used as input for any MediaPipe vision tasks, inference will be performed
|
* Hence, if this image is used as input for any MediaPipe vision tasks, inference will be
|
||||||
* on the it without any rotation. To create an `MPPImage` with a different orientation, please
|
* performed on the it without any rotation. To create an `MPPImage` with a different orientation,
|
||||||
* use `[MPPImage initWithImage:orientation:error:]`.
|
* please use `[MPPImage initWithImage:orientation:error:]`.
|
||||||
*
|
*
|
||||||
* @param image The image to use as the source. Its `CGImage` property must not be `NULL`.
|
* @param image The image to use as the source. Its `CGImage` property must not be `NULL`.
|
||||||
* @param error An optional error parameter populated when there is an error in initializing the
|
* @param error An optional error parameter populated when there is an error in initializing the
|
||||||
|
@ -99,9 +99,9 @@ NS_SWIFT_NAME(MPImage)
|
||||||
* Initializes an `MPPImage` object with the given pixel buffer.
|
* Initializes an `MPPImage` object with the given pixel buffer.
|
||||||
*
|
*
|
||||||
* The orientation of the newly created `MPPImage` will be `UIImageOrientationUp`.
|
* The orientation of the newly created `MPPImage` will be `UIImageOrientationUp`.
|
||||||
* Hence, if this image is used as input for any MediaPipe vision tasks, inference will be performed
|
* Hence, if this image is used as input for any MediaPipe vision tasks, inference will be
|
||||||
* on the it without any rotation. To create an `MPPImage` with a different orientation, please
|
* performed on the it without any rotation. To create an `MPPImage` with a different
|
||||||
* use `[MPPImage initWithPixelBuffer:orientation:error:]`.
|
* orientation, please use `[MPPImage initWithPixelBuffer:orientation:error:]`.
|
||||||
*
|
*
|
||||||
* @param pixelBuffer The pixel buffer to use as the source. It will be retained by the new
|
* @param pixelBuffer The pixel buffer to use as the source. It will be retained by the new
|
||||||
* `MPPImage` instance for the duration of its lifecycle.
|
* `MPPImage` instance for the duration of its lifecycle.
|
||||||
|
@ -136,14 +136,14 @@ NS_SWIFT_NAME(MPImage)
|
||||||
* Initializes an `MPPImage` object with the given sample buffer.
|
* Initializes an `MPPImage` object with the given sample buffer.
|
||||||
*
|
*
|
||||||
* The orientation of the newly created `MPPImage` will be `UIImageOrientationUp`.
|
* The orientation of the newly created `MPPImage` will be `UIImageOrientationUp`.
|
||||||
* Hence, if this image is used as input for any MediaPipe vision tasks, inference will be performed
|
* Hence, if this image is used as input for any MediaPipe vision tasks, inference will be
|
||||||
* on the it without any rotation. To create an `MPPImage` with a different orientation, please
|
* performed on the it without any rotation. To create an `MPPImage` with a different orientation,
|
||||||
* use `[MPPImage initWithSampleBuffer:orientation:error:]`.
|
* please use `[MPPImage initWithSampleBuffer:orientation:error:]`.
|
||||||
*
|
*
|
||||||
* @param sampleBuffer The sample buffer to use as the source. It will be retained by the new
|
* @param sampleBuffer The sample buffer to use as the source. It will be retained by the new
|
||||||
* `MPPImage` instance for the duration of its lifecycle. The sample buffer must be based on
|
* `MPPImage` instance for the duration of its lifecycle. The sample buffer must be based on
|
||||||
* a pixel buffer (not compressed data). In practice, it should be the video output of the camera on
|
* a pixel buffer (not compressed data). In practice, it should be the video output of the
|
||||||
* an iOS device, not other arbitrary types of `CMSampleBuffer`s.
|
* camera on an iOS device, not other arbitrary types of `CMSampleBuffer`s.
|
||||||
* @return A new `MPPImage` instance with the given sample buffer as the source. `nil` if the
|
* @return A new `MPPImage` instance with the given sample buffer as the source. `nil` if the
|
||||||
* given sample buffer is `nil` or invalid.
|
* given sample buffer is `nil` or invalid.
|
||||||
*/
|
*/
|
||||||
|
@ -158,8 +158,8 @@ NS_SWIFT_NAME(MPImage)
|
||||||
*
|
*
|
||||||
* @param sampleBuffer The sample buffer to use as the source. It will be retained by the new
|
* @param sampleBuffer The sample buffer to use as the source. It will be retained by the new
|
||||||
* `MPPImage` instance for the duration of its lifecycle. The sample buffer must be based on
|
* `MPPImage` instance for the duration of its lifecycle. The sample buffer must be based on
|
||||||
* a pixel buffer (not compressed data). In practice, it should be the video output of the camera on
|
* a pixel buffer (not compressed data). In practice, it should be the video output of the
|
||||||
* an iOS device, not other arbitrary types of `CMSampleBuffer`s.
|
* camera on an iOS device, not other arbitrary types of `CMSampleBuffer`s.
|
||||||
* @param orientation The display orientation of the image.
|
* @param orientation The display orientation of the image.
|
||||||
* @return A new `MPPImage` instance with the given orientation and sample buffer as the source.
|
* @return A new `MPPImage` instance with the given orientation and sample buffer as the source.
|
||||||
* `nil` if the given sample buffer is `nil` or invalid.
|
* `nil` if the given sample buffer is `nil` or invalid.
|
||||||
|
|
|
@ -13,3 +13,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
|
|
||||||
|
exports_files([
|
||||||
|
"version_script.lds",
|
||||||
|
])
|
||||||
|
|
|
@ -34,12 +34,17 @@ android_library(
|
||||||
# The native library of all MediaPipe audio tasks.
|
# The native library of all MediaPipe audio tasks.
|
||||||
cc_binary(
|
cc_binary(
|
||||||
name = "libmediapipe_tasks_audio_jni.so",
|
name = "libmediapipe_tasks_audio_jni.so",
|
||||||
|
linkopts = [
|
||||||
|
"-Wl,--no-undefined",
|
||||||
|
"-Wl,--version-script,$(location //mediapipe/tasks/java:version_script.lds)",
|
||||||
|
],
|
||||||
linkshared = 1,
|
linkshared = 1,
|
||||||
linkstatic = 1,
|
linkstatic = 1,
|
||||||
deps = [
|
deps = [
|
||||||
"//mediapipe/java/com/google/mediapipe/framework/jni:mediapipe_framework_jni",
|
"//mediapipe/java/com/google/mediapipe/framework/jni:mediapipe_framework_jni",
|
||||||
"//mediapipe/tasks/cc/audio/audio_classifier:audio_classifier_graph",
|
"//mediapipe/tasks/cc/audio/audio_classifier:audio_classifier_graph",
|
||||||
"//mediapipe/tasks/cc/audio/audio_embedder:audio_embedder_graph",
|
"//mediapipe/tasks/cc/audio/audio_embedder:audio_embedder_graph",
|
||||||
|
"//mediapipe/tasks/java:version_script.lds",
|
||||||
"//mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni:model_resources_cache_jni",
|
"//mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni:model_resources_cache_jni",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -19,12 +19,17 @@ package(default_visibility = ["//visibility:public"])
|
||||||
# The native library of all MediaPipe text tasks.
|
# The native library of all MediaPipe text tasks.
|
||||||
cc_binary(
|
cc_binary(
|
||||||
name = "libmediapipe_tasks_text_jni.so",
|
name = "libmediapipe_tasks_text_jni.so",
|
||||||
|
linkopts = [
|
||||||
|
"-Wl,--no-undefined",
|
||||||
|
"-Wl,--version-script,$(location //mediapipe/tasks/java:version_script.lds)",
|
||||||
|
],
|
||||||
linkshared = 1,
|
linkshared = 1,
|
||||||
linkstatic = 1,
|
linkstatic = 1,
|
||||||
deps = [
|
deps = [
|
||||||
"//mediapipe/java/com/google/mediapipe/framework/jni:mediapipe_framework_jni",
|
"//mediapipe/java/com/google/mediapipe/framework/jni:mediapipe_framework_jni",
|
||||||
"//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph",
|
"//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph",
|
||||||
"//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph",
|
"//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph",
|
||||||
|
"//mediapipe/tasks/java:version_script.lds",
|
||||||
"//mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni:model_resources_cache_jni",
|
"//mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni:model_resources_cache_jni",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,6 +36,10 @@ android_library(
|
||||||
# The native library of all MediaPipe vision tasks.
|
# The native library of all MediaPipe vision tasks.
|
||||||
cc_binary(
|
cc_binary(
|
||||||
name = "libmediapipe_tasks_vision_jni.so",
|
name = "libmediapipe_tasks_vision_jni.so",
|
||||||
|
linkopts = [
|
||||||
|
"-Wl,--no-undefined",
|
||||||
|
"-Wl,--version-script,$(location //mediapipe/tasks/java:version_script.lds)",
|
||||||
|
],
|
||||||
linkshared = 1,
|
linkshared = 1,
|
||||||
linkstatic = 1,
|
linkstatic = 1,
|
||||||
deps = [
|
deps = [
|
||||||
|
@ -46,6 +50,7 @@ cc_binary(
|
||||||
"//mediapipe/tasks/cc/vision/image_embedder:image_embedder_graph",
|
"//mediapipe/tasks/cc/vision/image_embedder:image_embedder_graph",
|
||||||
"//mediapipe/tasks/cc/vision/image_segmenter:image_segmenter_graph",
|
"//mediapipe/tasks/cc/vision/image_segmenter:image_segmenter_graph",
|
||||||
"//mediapipe/tasks/cc/vision/object_detector:object_detector_graph",
|
"//mediapipe/tasks/cc/vision/object_detector:object_detector_graph",
|
||||||
|
"//mediapipe/tasks/java:version_script.lds",
|
||||||
"//mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni:model_resources_cache_jni",
|
"//mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni:model_resources_cache_jni",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
24
mediapipe/tasks/java/version_script.lds
Normal file
24
mediapipe/tasks/java/version_script.lds
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
VERS_1.0 {
|
||||||
|
# Export JNI and native C symbols.
|
||||||
|
global:
|
||||||
|
Java_com_google_mediapipe_framework_AndroidAssetUtil*;
|
||||||
|
Java_com_google_mediapipe_framework_AndroidPacketCreator*;
|
||||||
|
Java_com_google_mediapipe_framework_Graph_nativeAddMultiStreamCallback;
|
||||||
|
Java_com_google_mediapipe_framework_Graph_nativeAddPacketToInputStream;
|
||||||
|
Java_com_google_mediapipe_framework_Graph_nativeCloseAllPacketSources;
|
||||||
|
Java_com_google_mediapipe_framework_Graph_nativeCreateGraph;
|
||||||
|
Java_com_google_mediapipe_framework_Graph_nativeLoadBinaryGraph*;
|
||||||
|
Java_com_google_mediapipe_framework_Graph_nativeMovePacketToInputStream;
|
||||||
|
Java_com_google_mediapipe_framework_Graph_nativeReleaseGraph;
|
||||||
|
Java_com_google_mediapipe_framework_Graph_nativeStartRunningGraph;
|
||||||
|
Java_com_google_mediapipe_framework_Graph_nativeWaitUntilGraphDone;
|
||||||
|
Java_com_google_mediapipe_framework_Graph_nativeWaitUntilGraphIdle;
|
||||||
|
Java_com_google_mediapipe_framework_PacketCreator*;
|
||||||
|
Java_com_google_mediapipe_framework_PacketGetter*;
|
||||||
|
Java_com_google_mediapipe_framework_Packet*;
|
||||||
|
Java_com_google_mediapipe_tasks_core_ModelResourcesCache*;
|
||||||
|
|
||||||
|
# Hide everything else.
|
||||||
|
local:
|
||||||
|
*;
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
diff --git a/tensorflow/core/lib/monitoring/percentile_sampler.cc b/tensorflow/core/lib/monitoring/percentile_sampler.cc
|
diff --git a/tensorflow/tsl/lib/monitoring/percentile_sampler.cc b/tensorflow/tsl/lib/monitoring/percentile_sampler.cc
|
||||||
index b7c22ae77ba..d0ba7b48b4b 100644
|
index b7c22ae77ba..d0ba7b48b4b 100644
|
||||||
--- a/tensorflow/core/lib/monitoring/percentile_sampler.cc
|
--- a/tensorflow/tsl/lib/monitoring/percentile_sampler.cc
|
||||||
+++ b/tensorflow/core/lib/monitoring/percentile_sampler.cc
|
+++ b/tensorflow/tsl/lib/monitoring/percentile_sampler.cc
|
||||||
@@ -29,7 +29,8 @@ namespace monitoring {
|
@@ -29,7 +29,8 @@ namespace monitoring {
|
||||||
void PercentileSamplerCell::Add(double sample) {
|
void PercentileSamplerCell::Add(double sample) {
|
||||||
uint64 nstime = EnvTime::NowNanos();
|
uint64 nstime = EnvTime::NowNanos();
|
||||||
|
@ -23,18 +23,6 @@ index b7c22ae77ba..d0ba7b48b4b 100644
|
||||||
pct_samples.points.push_back(pct);
|
pct_samples.points.push_back(pct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff --git a/tensorflow/core/platform/test.h b/tensorflow/core/platform/test.h
|
|
||||||
index b598b6ee1e4..51c013a2d62 100644
|
|
||||||
--- a/tensorflow/core/platform/test.h
|
|
||||||
+++ b/tensorflow/core/platform/test.h
|
|
||||||
@@ -40,7 +40,6 @@ limitations under the License.
|
|
||||||
// better error messages, more maintainable tests and more test coverage.
|
|
||||||
#if !defined(PLATFORM_GOOGLE) && !defined(PLATFORM_GOOGLE_ANDROID) && \
|
|
||||||
!defined(PLATFORM_CHROMIUMOS)
|
|
||||||
-#include <gmock/gmock-generated-matchers.h>
|
|
||||||
#include <gmock/gmock-matchers.h>
|
|
||||||
#include <gmock/gmock-more-matchers.h>
|
|
||||||
#endif
|
|
||||||
diff --git a/third_party/eigen3/eigen_archive.BUILD b/third_party/eigen3/eigen_archive.BUILD
|
diff --git a/third_party/eigen3/eigen_archive.BUILD b/third_party/eigen3/eigen_archive.BUILD
|
||||||
index 5514f774c35..1a38f76f4e9 100644
|
index 5514f774c35..1a38f76f4e9 100644
|
||||||
--- a/third_party/eigen3/eigen_archive.BUILD
|
--- a/third_party/eigen3/eigen_archive.BUILD
|
||||||
|
|
48
third_party/wasm_files.bzl
vendored
48
third_party/wasm_files.bzl
vendored
|
@ -12,72 +12,72 @@ def wasm_files():
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_audio_wasm_internal_js",
|
name = "com_google_mediapipe_wasm_audio_wasm_internal_js",
|
||||||
sha256 = "d4d205d08e3e1b09662a9a358d0107e8a8023827ba9b6982a3777bb6c040f936",
|
sha256 = "65139435bd64ff2f7791145e3b84b90200ba97edf78ea2a0feff7964dd9f5b9a",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.js?generation=1673996821002628"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.js?generation=1675786135168186"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_audio_wasm_internal_wasm",
|
name = "com_google_mediapipe_wasm_audio_wasm_internal_wasm",
|
||||||
sha256 = "1b2ffe82b0a25d20188237a724a7cad68d068818a7738f91c69c782314f55965",
|
sha256 = "b0aa60df4388ae2adee9ddf8e1f37932518266e088ecd531756e16d147ef5f7b",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.wasm?generation=1673996823772372"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.wasm?generation=1675786138391747"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_js",
|
name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_js",
|
||||||
sha256 = "1f367c2d667628b178251aec7fd464327351570edac4549450b11fb82f5f0fd4",
|
sha256 = "5e5d4975f5bf74b0d5f5601954ea221d73c4ee4f845e331a43244896ce0423de",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.js?generation=1673996826132845"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.js?generation=1675786141452578"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_wasm",
|
name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_wasm",
|
||||||
sha256 = "35c6ad888c06025dba1f9c8edb70e6c7be7e94e45dc2c0236a2fcfe61991dc44",
|
sha256 = "c2aed5747c85431b5c4f44947811bf19ca964a60ac3d2aab33e15612840da0a9",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.wasm?generation=1673996828935550"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.wasm?generation=1675786144663772"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_text_wasm_internal_js",
|
name = "com_google_mediapipe_wasm_text_wasm_internal_js",
|
||||||
sha256 = "68c0134e0b3cb986c3526cd645f74cc5a1f6ab19292276ca7d3558b89801e205",
|
sha256 = "14f408878d72139c81dafea6ca4ee4301d84ba5651ead9ac170f253dd3b0b6cd",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.js?generation=1673996831356232"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.js?generation=1675786147103241"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_text_wasm_internal_wasm",
|
name = "com_google_mediapipe_wasm_text_wasm_internal_wasm",
|
||||||
sha256 = "df82bb192ea852dc1bcc8f9f28fbd8c3d6b219dc4fec2b2a92451678d98ee1f0",
|
sha256 = "9807d302c5d020c2f49d1132ab9d9c717bcb9a18a01efa1b7993de1e9cab193b",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.wasm?generation=1673996834657078"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.wasm?generation=1675786150390358"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_js",
|
name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_js",
|
||||||
sha256 = "de1a4aabefb2e42ae4fee68b7e762e328623a163257a7ddc72365fc2502bd090",
|
sha256 = "5f25b455c989c80c86c4b4941118af8a4a82518eaebdb3d019bea674761160f9",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.js?generation=1673996837104551"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.js?generation=1675786153084313"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_wasm",
|
name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_wasm",
|
||||||
sha256 = "828dd1e73fa9478a97a62539117f92b813833ab35d37a986c466df15a8cfdc7b",
|
sha256 = "ec66757749832ddf5e7d8754a002f19bc4f0ce7539fc86be502afda376cc2e47",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.wasm?generation=1673996840120504"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.wasm?generation=1675786156694332"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_vision_wasm_internal_js",
|
name = "com_google_mediapipe_wasm_vision_wasm_internal_js",
|
||||||
sha256 = "c146b68523c256d41132230e811fc224dafb6a0bce6fc318c29dad37dfac06de",
|
sha256 = "97783273ec64885e1e0c56152d3b87ea487f66be3a1dfa9d87d4550d01d852cc",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.js?generation=1673996842448396"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.js?generation=1675786159557943"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_vision_wasm_internal_wasm",
|
name = "com_google_mediapipe_wasm_vision_wasm_internal_wasm",
|
||||||
sha256 = "8dbccaaf944ef1251cf78190450ab7074abea233e18ebb37d2c2ce0f18d14a0c",
|
sha256 = "f164caa065d57661cac31c36ebe1d3879d2618a9badee950312c682b7b5422d9",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.wasm?generation=1673996845499070"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.wasm?generation=1675786162975564"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_js",
|
name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_js",
|
||||||
sha256 = "705f9e3c2c62d12903ea2cadc22d2c328bc890f96fffc47b51f989471196ecea",
|
sha256 = "781d0c8e49d8c231ca5ae9b70effc57c067936c56d4eea4f8e5c5fb68865e17f",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.js?generation=1673996847915731"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.js?generation=1675786165851806"],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_file(
|
http_file(
|
||||||
name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_wasm",
|
name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_wasm",
|
||||||
sha256 = "c7ff6a7d8dc22380e2e8457a15a51b6bc1e70c6262fecca25825f54ecc593d1f",
|
sha256 = "7636c15555e9ba715afd6f0c64d7150ba39a82fc1fca659799d05cdbaccfe396",
|
||||||
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.wasm?generation=1673996850980344"],
|
urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.wasm?generation=1675786169149137"],
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user