Compare commits

..
628 Commits
Author SHA1 Message Date
Sebastian SchmidtandCopybara-Service d392f8ad98 Ensure that -std=c++14/17 is the first argument passed to Glog
PiperOrigin-RevId: 552509553
2023-07-31 09:47:32 -07:00
Sebastian SchmidtandCopybara-Service 81cf7fa173 Updat WASM binaries for 0.10.3 release
PiperOrigin-RevId: 551975834
2023-07-28 16:17:30 -07:00
MediaPipe TeamandCopybara-Service 8e313b4b0c Fix typo in model maker requirements.txt
PiperOrigin-RevId: 551973577
2023-07-28 16:07:12 -07:00
Sebastian SchmidtandCopybara-Service b4bcfab4f5 Remove extra letter from text classifier API
PiperOrigin-RevId: 551942087
2023-07-28 13:56:56 -07:00
Sebastian SchmidtandCopybara-Service 8ab9185c1d Use C+++ 17 for Glog only on Windows
PiperOrigin-RevId: 551928369
2023-07-28 12:58:42 -07:00
MediaPipe TeamandCopybara-Service 3f7752561b No public description
PiperOrigin-RevId: 551914786
2023-07-28 12:05:38 -07:00
MediaPipe TeamandCopybara-Service 9edb059d9f No public description
PiperOrigin-RevId: 551868738
2023-07-28 09:09:39 -07:00
MediaPipe TeamandCopybara-Service 7db0c1944b Internal change
PiperOrigin-RevId: 551789915
2023-07-28 02:29:52 -07:00
MediaPipe TeamandCopybara-Service db9a72a5df Internal Changes
PiperOrigin-RevId: 551674542
2023-07-27 16:35:35 -07:00
MediaPipe TeamandCopybara-Service 5c007558f8 internal change.
PiperOrigin-RevId: 551645248
2023-07-27 14:45:18 -07:00
Sebastian SchmidtandCopybara-Service 4d5c6bd33a Internal
PiperOrigin-RevId: 551625147
2023-07-27 13:33:14 -07:00
Sebastian SchmidtandCopybara-Service fdea10d230 Add C Headers for Text Classifier
PiperOrigin-RevId: 551618765
2023-07-27 13:09:49 -07:00
MediaPipe TeamandCopybara-Service 5b31f1e3e9 Update glog to latest commit
PiperOrigin-RevId: 551601991
2023-07-27 12:07:20 -07:00
Sebastian SchmidtandCopybara-Service 7d9cb4ee67 No public description
PiperOrigin-RevId: 551586945
2023-07-27 11:17:54 -07:00
MediaPipe TeamandCopybara-Service f3f9e71ccb No public description
PiperOrigin-RevId: 551549511
2023-07-27 09:15:46 -07:00
MediaPipe TeamandCopybara-Service 6de275834d internal change.
PiperOrigin-RevId: 551366789
2023-07-26 17:59:06 -07:00
Sebastian SchmidtandCopybara-Service c9d79a0076 Rollback of "Fix duplicate condition error in :resource_util"
PiperOrigin-RevId: 551332734
2023-07-26 15:31:51 -07:00
Sebastian SchmidtandCopybara-Service dad46e1e90 Update glog to 0.6
PiperOrigin-RevId: 551330044
2023-07-26 15:20:34 -07:00
Sebastian SchmidtandCopybara-Service f156397e8f Fix Android build with any Protos
PiperOrigin-RevId: 551325541
2023-07-26 15:04:38 -07:00
MediaPipe TeamandCopybara-Service fa5c1b03d2 No public description
PiperOrigin-RevId: 551277242
2023-07-26 12:08:33 -07:00
Sebastian SchmidtandCopybara-Service 87b925795d Update glog to 0.6
PiperOrigin-RevId: 551269455
2023-07-26 11:41:24 -07:00
Sebastian SchmidtandCopybara-Service 750f498b14 Internal
PiperOrigin-RevId: 551247471
2023-07-26 10:33:19 -07:00
MediaPipe TeamandCopybara-Service 1f6851c577 C++ Image segmenter add output size parameters.
PiperOrigin-RevId: 550995124
2023-07-25 14:22:11 -07:00
MediaPipe TeamandCopybara-Service bd7888cc0c 1. Move evaluation onto GPU/TPU hardware if available.
2. Move desired_precision and desired_recall from evaluate to hyperparameters so recall@precision metrics will be reported for both training and evaluation. This also fixes a bug where recompiling the model with the previously initialized metric objects would not properly reset the metric states.
3. Remove redundant label_names from create_... class methods in text_classifier. This information is already provided by the datasets.
4. Change loss function to FocalLoss.
5. Re-enable text_classifier unit tests using ExBert
6. Add input names to avoid flaky auto-assigned input names.

PiperOrigin-RevId: 550992146
2023-07-25 14:12:26 -07:00
MediaPipe TeamandCopybara-Service 85c3fed70a Add class weights to core hyperparameters and classifier library.
PiperOrigin-RevId: 550962843
2023-07-25 12:29:46 -07:00
MediaPipe TeamandCopybara-Service 62538a9496 No public description
PiperOrigin-RevId: 550954023
2023-07-25 11:57:08 -07:00
MediaPipe TeamandCopybara-Service 113c9b30c2 No public description
PiperOrigin-RevId: 550616150
2023-07-24 11:09:31 -07:00
Copybara-Service 66cceddb5e Merge pull request #4639 from priankakariatyml:ios-image-segmenter-container-utils
PiperOrigin-RevId: 550608973
2023-07-24 10:46:56 -07:00
Prianka Liz Kariat 72c62f7d5d Added iOS Image Segmenter Header 2023-07-24 20:38:16 +05:30
MediaPipe TeamandCopybara-Service 25b01784de Fix documentation
PiperOrigin-RevId: 549968822
2023-07-21 09:33:48 -07:00
MediaPipe TeamandCopybara-Service 9af637b125 Java API add visibility and presence for landmarks.
PiperOrigin-RevId: 549709256
2023-07-20 12:42:01 -07:00
Copybara-Service 236a36e39a Merge pull request #4629 from priankakariatyml:ios-vision-library-fixes
PiperOrigin-RevId: 549659874
2023-07-20 09:52:11 -07:00
Prianka Liz Kariat 540f4f7fe6 Fixed swift name of iOS face landmarker delegate 2023-07-20 15:57:37 +05:30
Prianka Liz Kariat 3198ccf6a5 Added missing headers in ios vision framework build 2023-07-20 15:57:16 +05:30
Steven HicksonandCopybara-Service e47af74b15 Adding support for 2 things in tensors_to_image_calculator:
1) 1 channel support for conversion after inference.
2) multitask support by allowing for different tensor outputs.

PiperOrigin-RevId: 549412331
2023-07-19 13:41:46 -07:00
MediaPipe TeamandCopybara-Service 085840388b Move waitOnCpu and waitOnGpu out of the synchronized block, which can cause deadlock.
PiperOrigin-RevId: 549217916
2023-07-18 23:42:01 -07:00
MediaPipe TeamandCopybara-Service 4e72fcf0cb Replace CHECK with RET_CHECK in GetContract() implementation from six calculators.
PiperOrigin-RevId: 549158984
2023-07-18 17:38:44 -07:00
MediaPipe TeamandCopybara-Service 4c60fe7365 add pose landmarks connections in C++ API
PiperOrigin-RevId: 549108310
2023-07-18 14:21:02 -07:00
MediaPipe TeamandCopybara-Service 9b00582f21 add hand landmarks connections in C++ API.
PiperOrigin-RevId: 549108307
2023-07-18 14:16:27 -07:00
MediaPipe TeamandCopybara-Service cb915858fa Internal change
PiperOrigin-RevId: 549052451
2023-07-18 11:01:37 -07:00
Jiuqiang TangandCopybara-Service 0c01187cf5 Internal change
PiperOrigin-RevId: 548886447
2023-07-17 21:57:24 -07:00
MediaPipe TeamandCopybara-Service ef12ce8575 Internal change
PiperOrigin-RevId: 548821518
2023-07-17 15:56:05 -07:00
MediaPipe TeamandCopybara-Service f1f9f80cd9 Internal change
PiperOrigin-RevId: 548746432
2023-07-17 11:18:00 -07:00
MediaPipe TeamandCopybara-Service 17bc1a5ab5 Internal change
PiperOrigin-RevId: 548196034
2023-07-14 12:39:45 -07:00
MediaPipe TeamandCopybara-Service 2fae07375c Discard outdated packets earlier in MuxInputStreamHandler.
In our pipeline, a deadlock is detected because the packets in deselected
data streams get piled up. In the current implementation, those packets only get
removed in FillInputSet(), but we should also do that in GetNodeReadiness().

PiperOrigin-RevId: 548051369
2023-07-14 01:12:14 -07:00
MediaPipe TeamandCopybara-Service 723e91cec1 Generalize non-define registration with MEDIAPIPE_STATIC_REGISTRATOR_TEMPLATE
PiperOrigin-RevId: 547929982
2023-07-13 14:52:37 -07:00
MediaPipe TeamandCopybara-Service c2c67c20fa Internal change
PiperOrigin-RevId: 547924907
2023-07-13 14:37:40 -07:00
Sebastian SchmidtandCopybara-Service 327feb42d1 Support WASM asset loading for MediaPipe Task Web
PiperOrigin-RevId: 547882566
2023-07-13 12:26:59 -07:00
MediaPipe TeamandCopybara-Service 8b59567cb7 Add proto3 Any proto support for Java task api
PiperOrigin-RevId: 547836041
2023-07-13 10:10:17 -07:00
MediaPipe TeamandCopybara-Service e37bedd344 Fix Halide BUILD rules
PiperOrigin-RevId: 547755467
2023-07-13 04:47:34 -07:00
MediaPipe TeamandCopybara-Service 251c5421f6 Internal change
PiperOrigin-RevId: 547735699
2023-07-13 02:53:16 -07:00
MediaPipe TeamandCopybara-Service 450c933cb5 MEDIAPIPE_NODE/SUBGRAPH_IMPLEMENTATION to use common define for registration
PiperOrigin-RevId: 547669538
2023-07-12 20:10:15 -07:00
MediaPipe TeamandCopybara-Service cc2aa4f4cc InferenceCalculatorAdvancedGL save cache in Open().
PiperOrigin-RevId: 547652481
2023-07-12 18:09:51 -07:00
MediaPipe TeamandCopybara-Service a2cd3e7f95 Internal change
PiperOrigin-RevId: 547614484
2023-07-12 15:17:40 -07:00
MediaPipe TeamandCopybara-Service 37b68714b8 Internal change
PiperOrigin-RevId: 547424721
2023-07-12 01:32:51 -07:00
MediaPipe TeamandCopybara-Service 3e93cbc838 Internal change
PiperOrigin-RevId: 547404737
2023-07-12 00:04:40 -07:00
Yilei YangandCopybara-Service 917af2ce6b Internal change
PiperOrigin-RevId: 547346939
2023-07-11 17:52:07 -07:00
Sebastian SchmidtandCopybara-Service f2f49b9fc8 Add angle to BoundingBox
PiperOrigin-RevId: 547321781
2023-07-11 16:00:35 -07:00
MediaPipe TeamandCopybara-Service aabf61f28d Internal Change
PiperOrigin-RevId: 547299595
2023-07-11 14:35:18 -07:00
MediaPipe TeamandCopybara-Service 56bc019819 Model Maker allow core dataset library to handle datasets with unknown sizes.
PiperOrigin-RevId: 547268411
2023-07-11 12:47:37 -07:00
MediaPipe TeamandCopybara-Service 4788fddde9 Internal Change
PiperOrigin-RevId: 547265380
2023-07-11 12:34:32 -07:00
MediaPipe TeamandCopybara-Service e4ec4d2526 Internal change
PiperOrigin-RevId: 547258228
2023-07-11 12:05:58 -07:00
MediaPipe TeamandCopybara-Service bf6561ce91 add symmetric color style option
PiperOrigin-RevId: 547069284
2023-07-10 21:41:01 -07:00
MediaPipe TeamandCopybara-Service 0bde987a38 Removed internal dependency on OpenCV 3.x, migrating it to OpenCV 4.x
PiperOrigin-RevId: 546945166
2023-07-10 12:17:54 -07:00
Copybara-Service df3f4167ae Merge pull request #4600 from priankakariatyml:ios-orientation-fix
PiperOrigin-RevId: 546358930
2023-07-07 12:56:39 -07:00
Sebastian SchmidtandCopybara-Service 03bc9d64f2 Update glog to 0.6
PiperOrigin-RevId: 546349096
2023-07-07 12:22:13 -07:00
MediaPipe TeamandCopybara-Service d45b15ef84 Add face landmarks connections for C++.
PiperOrigin-RevId: 546345842
2023-07-07 12:08:09 -07:00
Sebastian SchmidtandCopybara-Service 1614c5a542 Update WASM files for 0.10.2 release
PiperOrigin-RevId: 546332490
2023-07-07 11:20:13 -07:00
Prianka Liz Kariat cae10ea115 Updated documentation of MPImage 2023-07-07 22:03:15 +05:30
Prianka Liz Kariat 7556a3f1b4 Changed left and right image orientation angles to match iOS UIImageOrientation 2023-07-07 19:57:44 +05:30
MediaPipe TeamandCopybara-Service cb1035a9ee Internal change
PiperOrigin-RevId: 546090489
2023-07-06 14:24:31 -07:00
Yoni Ben-MeshulamandCopybara-Service 0a198d1f6a Fix a typo in proto doc.
PiperOrigin-RevId: 546049240
2023-07-06 14:20:09 -07:00
MediaPipe TeamandCopybara-Service 15ee1210e5 Internal change
PiperOrigin-RevId: 546035969
2023-07-06 10:58:20 -07:00
Copybara-Service a851863e9c Merge pull request #4590 from priankakariatyml:ios-image-segmenter-container-utils
PiperOrigin-RevId: 546018332
2023-07-06 09:57:59 -07:00
Prianka Liz Kariat 823d5b39af Fixed typo 2023-07-06 18:46:01 +05:30
Sebastian SchmidtandCopybara-Service 9861b3c8a8 Fix bounds calculation in RefineLandmarksFromHeatMapCalculator
Fixes https://github.com/google/mediapipe/issues/4414

PiperOrigin-RevId: 545794151
2023-07-05 14:58:36 -07:00
MediaPipe TeamandCopybara-Service 74f484d96d Internal change
PiperOrigin-RevId: 545658434
2023-07-05 07:09:40 -07:00
MediaPipe TeamandCopybara-Service dbe8e40124 Internal change
PiperOrigin-RevId: 545045282
2023-07-03 10:04:19 -07:00
Prianka Liz Kariat 9b7e233fe3 Added Image Segmenter Result Helpers 2023-07-03 20:48:29 +05:30
Prianka Liz Kariat cebb0a2c2e Added iOS Image Segmenter Options Helpers 2023-07-03 20:48:15 +05:30
MediaPipe TeamandCopybara-Service 7ba21e9a9a Revert Add location info in registry (debug mode only)
PiperOrigin-RevId: 544842663
2023-07-01 01:11:02 -07:00
MediaPipe TeamandCopybara-Service 422556c4a3 Internal change
PiperOrigin-RevId: 544663494
2023-06-30 08:34:32 -07:00
Jiuqiang TangandCopybara-Service 6c7aa8a0d6 Internal change
PiperOrigin-RevId: 544563029
2023-06-29 23:05:37 -07:00
MediaPipe TeamandCopybara-Service 687075e5b8 Add gpu to cpu fallback for tensors_to_detections_calculator.
PiperOrigin-RevId: 544480883
2023-06-29 15:36:33 -07:00
MediaPipe TeamandCopybara-Service 0ea54b1461 Add delegate options to base options for java API. and add unit tset for BaseOptions.
PiperOrigin-RevId: 544458644
2023-06-29 14:13:46 -07:00
MediaPipe TeamandCopybara-Service e15d5a797b Do not send PreviousLoopback output packets to closed streams
PiperOrigin-RevId: 544449979
2023-06-29 13:44:56 -07:00
MediaPipe TeamandCopybara-Service 52cea59d41 Add keys for the context that better match the featurelist for text.
PiperOrigin-RevId: 544430289
2023-06-29 12:29:49 -07:00
MediaPipe TeamandCopybara-Service 0bb4ee8941 Add MobileNetV2_I320 and MobileNetMultiHWAVG_I384 to support larger input image sizes.
PiperOrigin-RevId: 544393692
2023-06-29 10:24:52 -07:00
MediaPipe TeamandCopybara-Service 8278dbc38f Exposes OpenCV photo lib.
PiperOrigin-RevId: 544092832
2023-06-28 10:22:07 -07:00
MediaPipe TeamandCopybara-Service 1ee55d1f1b Support ExBert training and option to select between AdamW and LAMB optimizers for BertClassifier
PiperOrigin-RevId: 543905014
2023-06-27 18:05:15 -07:00
MediaPipe TeamandCopybara-Service bed624f3b6 Shows the recently added warning when WaitUntilIdle is called with source nodes only once. Otherwise, it is very spammy as it's shown every frame. Moreover, display the names of the sources, so the warning is more actionable.
PiperOrigin-RevId: 543676454
2023-06-27 02:03:04 -07:00
MediaPipe TeamandCopybara-Service c8c5f3d062 Internal change
PiperOrigin-RevId: 543602625
2023-06-26 18:57:21 -07:00
MediaPipe TeamandCopybara-Service 9de1b2577f Internal update
PiperOrigin-RevId: 543508346
2023-06-26 12:26:51 -07:00
MediaPipe TeamandCopybara-Service 570880190b Internal change for proto library outputs.
PiperOrigin-RevId: 543368974
2023-06-26 01:52:50 -07:00
Copybara-Service 5d19a46956 Merge pull request #4561 from priankakariatyml:ios-segmentation-mask
PiperOrigin-RevId: 543295371
2023-06-25 17:37:35 -07:00
Copybara-Service 80a02f8f38 Merge pull request #4566 from priankakariatyml:ios-image-segmenter-containers
PiperOrigin-RevId: 542931120
2023-06-23 12:42:56 -07:00
Copybara-Service 0093f2040b Merge pull request #4567 from priankakariatyml:ios-running-mode-copy-fix
PiperOrigin-RevId: 542930036
2023-06-23 12:38:34 -07:00
Prianka Liz Kariat 3d79d58286 Updated variable name 2023-06-23 20:18:41 +05:30
Prianka Liz Kariat bfb68491af Added copying of running mode in NSCopying implementation in iOS tasks 2023-06-23 20:13:29 +05:30
Prianka Liz Kariat 5dce8f283d Updated image segmenter delegate method to be required 2023-06-23 20:10:42 +05:30
Prianka Liz Kariat 7623c5a941 Added iOS Image Segmenter Options 2023-06-23 20:09:18 +05:30
Prianka Liz Kariat 7fe365489d Added iOS Image Segmenter Result 2023-06-23 20:09:05 +05:30
MediaPipe TeamandCopybara-Service a8899da45a Fix -Wsign-compare warning in api2/builder.h
PiperOrigin-RevId: 542673286
2023-06-22 14:49:23 -07:00
MediaPipe TeamandCopybara-Service 4e862995ba Fix typo
PiperOrigin-RevId: 542660548
2023-06-22 14:02:16 -07:00
MediaPipe TeamandCopybara-Service 2f5fc16a38 Fix timestamp computation when copying within first block.
When computing the last copied sample's timestamp, first_block_offset_ needs to be taken into account.

PiperOrigin-RevId: 542643291
2023-06-22 13:03:36 -07:00
Jiuqiang TangandCopybara-Service 98d493f37a Add MatrixData as a packet option for ConstantSidePacketCalculatorOptions.
PiperOrigin-RevId: 542616847
2023-06-22 11:28:07 -07:00
MediaPipe TeamandCopybara-Service ba7e0e0e50 Add a face alignment preprocessor to face stylizer.
PiperOrigin-RevId: 542559764
2023-06-22 07:59:52 -07:00
Prianka Liz Kariat 7f39153ff3 Added MPPMask Tests 2023-06-22 17:44:07 +05:30
MediaPipe TeamandCopybara-Service 825e3a8af0 Speed up TimeSeriesFramerCalculator.
Currently, TimeSeriesFramerCalculator constructs a distinct Matrix object for every input sample, which is inefficient. This CL revises buffering to keep each input packet's worth of samples as one grouped Matrix. A benchmark is added, showing a speed up of about 20x.

```
name                               old      new
BM_TimeSeriesFramerCalculator  48.45ms   2.26ms
```

PiperOrigin-RevId: 542462618
2023-06-21 23:03:54 -07:00
MediaPipe TeamandCopybara-Service 0d2548cd65 Internal change
PiperOrigin-RevId: 542392817
2023-06-21 16:23:43 -07:00
MediaPipe TeamandCopybara-Service c86d80a031 Internal Changes
PiperOrigin-RevId: 542387813
2023-06-21 16:02:54 -07:00
MediaPipe TeamandCopybara-Service 895c685df6 1. Model maker core classifier change _metric_function field to _metric_functions in order to support having multiple metrics.
2. Add SparsePrecision, SparseRecall, BinarySparsePrecisionAtRecall, and BinarySparseRecallAtPrecision to the shared metrics library.
3. Add SparsePrecision, SparseRecall to text classifier, and have the option to evaluate the model with BinarySparsePrecisionAtRecall and BinarySparseRecallAtPrecision

PiperOrigin-RevId: 542376451
2023-06-21 15:19:29 -07:00
MediaPipe TeamandCopybara-Service 7edb6b8fcb add concatenate image vector calculator
PiperOrigin-RevId: 542084345
2023-06-20 16:40:11 -07:00
MediaPipe TeamandCopybara-Service 0b6ff84e3c update face drawing function.
PiperOrigin-RevId: 542083042
2023-06-20 16:34:27 -07:00
Sebastian SchmidtandCopybara-Service ef6aeb8828 Allow passing of HParams to MediaPipe training docker
PiperOrigin-RevId: 542052304
2023-06-20 14:39:38 -07:00
MediaPipe TeamandCopybara-Service 86bc764b6e This will fix typos in tasks internal files.
PiperOrigin-RevId: 541945726
2023-06-20 09:18:01 -07:00
Copybara-Service bd3a8d885d Merge pull request #4538 from priankakariatyml:ios-segmentation-mask
PiperOrigin-RevId: 541944396
2023-06-20 09:12:53 -07:00
MediaPipe TeamandCopybara-Service 35c79b755e update face drawing function.
PiperOrigin-RevId: 541055040
2023-06-16 17:46:11 -07:00
MediaPipe TeamandCopybara-Service 80208079d2 Use GFile for internal file systems.
PiperOrigin-RevId: 541041972
2023-06-16 16:45:56 -07:00
Copybara-Service 41215a3878 Merge pull request #4541 from priankakariatyml:ios-hand-landmarker-tests
PiperOrigin-RevId: 540995916
2023-06-16 14:07:49 -07:00
Sebastian SchmidtandCopybara-Service c5b1edd709 Add "exports" field definitions to package.json
Fixes https://github.com/google/mediapipe/issues/4547

PiperOrigin-RevId: 540977469
2023-06-16 13:14:09 -07:00
Prianka Liz Kariat d12dd88f51 Fixed implementation of init methods in MPPMask 2023-06-16 20:00:30 +05:30
Prianka Liz Kariat 4ab1a5de1b Reverted changes to iOS tasks deployment target 2023-06-16 19:59:59 +05:30
Prianka Liz Kariat fec2fc77e0 Revert "Revert "Updated init method implementations in MPPMask""
This reverts commit 52f6b8d899.
2023-06-16 19:56:32 +05:30
Prianka Liz Kariat 52f6b8d899 Revert "Updated init method implementations in MPPMask"
This reverts commit 83486ed01b.
2023-06-16 19:56:23 +05:30
Prianka Liz Kariat 83486ed01b Updated init method implementations in MPPMask 2023-06-16 19:56:04 +05:30
MediaPipe TeamandCopybara-Service 6f065bc405 Update Tensorflow dependency in MediaPipe
PiperOrigin-RevId: 540619536
2023-06-15 10:23:20 -07:00
Sebastian SchmidtandCopybara-Service e73ea23261 Internal change
PiperOrigin-RevId: 540603621
2023-06-15 09:26:01 -07:00
Prianka Liz Kariat 1f77fa9de4 Removed generic methods for alloc and memcpy from MPPMask 2023-06-15 16:07:56 +05:30
Prianka Liz Kariat 327547ec2b Updated variable names in MPPMask 2023-06-15 14:16:34 +05:30
Prianka Liz Kariat 9d0fed89ff Fixed documentation in MPPMask 2023-06-15 14:11:08 +05:30
Prianka Liz Kariat aa1ab18000 Updated documentation in MPPMask 2023-06-15 14:09:22 +05:30
Prianka Liz Kariat a7f555fcc2 Fixed float calculations in MPPMask 2023-06-15 14:07:33 +05:30
Prianka Liz Kariat c8f85ac060 Updated signature of initializer in MPPMask 2023-06-15 14:06:52 +05:30
MediaPipe TeamandCopybara-Service 2e48a0bce0 Remove designated initializers
PiperOrigin-RevId: 540471772
2023-06-14 22:17:20 -07:00
MediaPipe TeamandCopybara-Service e02d70f8e5 internal change
PiperOrigin-RevId: 540404812
2023-06-14 16:00:00 -07:00
Copybara-Service a2d4566845 Merge pull request #4542 from priankakariatyml:ios-hand-landmarker-updates
PiperOrigin-RevId: 540393678
2023-06-14 15:16:14 -07:00
MediaPipe TeamandCopybara-Service 4776ecf402 Internal change
PiperOrigin-RevId: 540361672
2023-06-14 13:23:36 -07:00
MediaPipe TeamandCopybara-Service a1be5f3e72 Add a test case for "summary packet" to test failing upstream calculator
PiperOrigin-RevId: 540331486
2023-06-14 11:34:17 -07:00
MediaPipe TeamandCopybara-Service 66a29bf371 Internal change
PiperOrigin-RevId: 540327302
2023-06-14 11:23:51 -07:00
Prianka Liz Kariat 9ed7acc0a3 Updated hand connections in iOS hand landmarker to class properties. 2023-06-14 15:59:54 +05:30
Prianka Liz Kariat 94a9464750 Fixed formatting in MPPHandLandmarkerTests.m 2023-06-14 15:52:26 +05:30
Prianka Liz Kariat 0ae27fad37 Updated iOS hand landmarker tests 2023-06-14 15:51:41 +05:30
Prianka Liz Kariat dffca9e3b5 Updated protobuf helper method name in iOS Gesture Recognizer Helpers 2023-06-14 15:51:06 +05:30
Prianka Liz Kariat 086798e677 Merge branch 'master' into ios-hand-landmarker-tests 2023-06-14 15:35:02 +05:30
Prianka Liz Kariat 43e51c1094 Added live stream mode tests for iOS Hand Landmarker 2023-06-14 15:34:32 +05:30
Yuqi LiandCopybara-Service eaeca82b76 Internal change
PiperOrigin-RevId: 540134258
2023-06-13 18:41:30 -07:00
MediaPipe TeamandCopybara-Service 3742bc8c1b Add metadata for all PREFIX/image... prefixes.
PiperOrigin-RevId: 540117214
2023-06-13 17:12:17 -07:00
MediaPipe TeamandCopybara-Service 02d55dfb0a Modify the TensorToImageFrameCalculator to support normalized outputs.
PiperOrigin-RevId: 540104988
2023-06-13 16:20:42 -07:00
MediaPipe TeamandCopybara-Service b97d11fa76 Internal MediaPipe Tasks change
PiperOrigin-RevId: 540083633
2023-06-13 15:05:04 -07:00
Copybara-Service 6cf7148f3b Merge pull request #4534 from priankakariatyml:ios-hand-landmarker-tests
PiperOrigin-RevId: 540030514
2023-06-13 11:58:26 -07:00
Prianka Liz Kariat 2cdb291e54 Removed core video import 2023-06-13 22:29:15 +05:30
Prianka Liz Kariat dddbcc4449 Updated data types of width and height 2023-06-13 22:28:09 +05:30
MediaPipe TeamandCopybara-Service e468bee584 Deprecate GraphStatus()
PiperOrigin-RevId: 539992850
2023-06-13 09:54:22 -07:00
Prianka Liz Kariat 5e2bb0e1db Updated documentation of MPPMask 2023-06-13 22:19:40 +05:30
Prianka Liz Kariat de9acdfa68 Added iOS segmentation mask 2023-06-13 22:17:41 +05:30
MediaPipe TeamandCopybara-Service b19b80e10f Add support for int64 constant side package value.
PiperOrigin-RevId: 539893314
2023-06-13 01:53:13 -07:00
MediaPipe TeamandCopybara-Service 96cc0fd07b Internal change
PiperOrigin-RevId: 539719443
2023-06-12 11:53:48 -07:00
MediaPipe TeamandCopybara-Service fe0d1b1e83 Internal change
PiperOrigin-RevId: 539675912
2023-06-12 09:28:26 -07:00
Sebastian SchmidtandCopybara-Service 8a2ec518de Use .mjs for ESM Modules and use .cjs for CommonJS
PiperOrigin-RevId: 539664711
2023-06-12 08:45:01 -07:00
Prianka Liz Kariat baa79046b9 Added iOS Objective C hand landmarker tests 2023-06-12 19:56:34 +05:30
Prianka Liz Kariat eff56045e4 Added hand landmarker protobuf utils 2023-06-12 19:56:20 +05:30
MediaPipe TeamandCopybara-Service ac4f60a793 Annotate in model input scale for InteractiveSegmenter
PiperOrigin-RevId: 539245617
2023-06-09 21:13:20 -07:00
MediaPipe TeamandCopybara-Service 1d4a205c2e Internal change
PiperOrigin-RevId: 539220863
2023-06-09 18:06:50 -07:00
MediaPipe TeamandCopybara-Service 53f0736bf0 Add an option to disable explicit CPU sync for ExternalTextureRenderer
PiperOrigin-RevId: 539166965
2023-06-09 13:42:14 -07:00
Sebastian SchmidtandCopybara-Service 67c5d8d224 Add FaceLandmarker constants for iOS
PiperOrigin-RevId: 539160195
2023-06-09 13:15:26 -07:00
Copybara-Service fb47218e10 Merge pull request #4526 from priankakariatyml:ios-hand-landmarker-implementation
PiperOrigin-RevId: 539145005
2023-06-09 12:12:42 -07:00
Prianka Liz Kariat f528fa5de2 Updated constant names in MPPHandLandmarkConnections 2023-06-09 17:30:23 +05:30
Copybara-Service 4c4a1d93b2 Merge pull request #4523 from priankakariatyml:ios-gesture-recognizer-add-tests
PiperOrigin-RevId: 538848389
2023-06-08 11:48:18 -07:00
Prianka Liz Kariat f63c00b3c6 Added hand landmarker implementation file and hand landmarker connections 2023-06-08 18:09:42 +05:30
MediaPipe TeamandCopybara-Service 943445fba8 Update base audio/vision tasks api to suuport proto3 graph options.
PiperOrigin-RevId: 538661975
2023-06-07 20:04:33 -07:00
Sebastian SchmidtandCopybara-Service a7cd7b9a32 Add CommonJS bundle for MediaPipe Tasks
Fixes https://github.com/google/mediapipe/issues/4398

PiperOrigin-RevId: 538539711
2023-06-07 11:12:37 -07:00
Ilya TokarandCopybara-Service 489e927410 Fix tests to work with arch haswell/sandybridge.
PiperOrigin-RevId: 538538356
2023-06-07 11:07:49 -07:00
Prianka Liz Kariat 10144a805a Added more tests to MPPGestureRecognizerTests.mm 2023-06-07 18:45:37 +05:30
Prianka Liz Kariat 8a5b443b86 Fixed typos in method names 2023-06-07 18:44:54 +05:30
MediaPipe TeamandCopybara-Service 4b0f3cacae Internal change
PiperOrigin-RevId: 538313290
2023-06-06 15:52:55 -07:00
Sebastian SchmidtandCopybara-Service d6f34f6aef Log the Bazel build
PiperOrigin-RevId: 538308030
2023-06-06 15:31:33 -07:00
Sebastian SchmidtandCopybara-Service 4a123445c4 Update rules_foreign_cc
Fixes https://github.com/google/mediapipe/issues/4365

PiperOrigin-RevId: 538301543
2023-06-06 15:08:00 -07:00
Sebastian SchmidtandCopybara-Service d063ed2c1e Rename MPPFaceLandmarker.m to MPPFaceLandmarker.mm
PiperOrigin-RevId: 538281740
2023-06-06 13:52:23 -07:00
Copybara-Service c71673d712 Merge pull request #4495 from priankakariatyml:ios-gesture-recognizer-tests
PiperOrigin-RevId: 538259988
2023-06-06 12:31:10 -07:00
Copybara-Service 70e00b4dbe Merge pull request #4497 from priankakariatyml:ios-hand-landmarker-utils
PiperOrigin-RevId: 538238944
2023-06-06 11:17:45 -07:00
Fergus HendersonandCopybara-Service 709eb812cc Internal change
PiperOrigin-RevId: 538215311
2023-06-06 10:00:52 -07:00
MediaPipe TeamandCopybara-Service 37290f0224 Port StreamToSidePacketCalculator to api2
PiperOrigin-RevId: 538109898
2023-06-06 01:34:43 -07:00
MediaPipe TeamandCopybara-Service ab72fccca7 Internal change
PiperOrigin-RevId: 537928827
2023-06-05 11:14:28 -07:00
Prianka Liz Kariat d256a3e670 Updated dictionary to generics in iOS gesture recognizer tests 2023-06-05 21:13:04 +05:30
Prianka Liz Kariat f213e0a6f3 Fixed typos 2023-06-05 13:47:11 +05:30
Prianka Liz Kariat 1496b7c2d4 Updated MPPGestureRecognizer tests to use generics 2023-06-05 13:40:56 +05:30
Prianka Liz Kariat 32195e6a83 Updated MPPGestureRecognizerTests to use generics for file path dicts 2023-06-05 13:39:44 +05:30
Prianka Liz Kariat e1d8854388 Merge branch 'master' into ios-gesture-recognizer-tests 2023-06-05 13:27:44 +05:30
Prianka Liz Kariat db0da30f18 Updated comments 2023-06-05 13:26:17 +05:30
Prianka Liz Kariat 56a035cb1b Updated method names in MPPGestureRecognizer 2023-06-05 13:21:39 +05:30
Prianka Liz Kariat 0c2a7bee09 Update iOS Gesture Recognizer error assertion 2023-06-05 13:19:39 +05:30
MediaPipe TeamandCopybara-Service cbf1d97429 Internal change
PiperOrigin-RevId: 537613648
2023-06-03 20:19:16 -07:00
Sebastian SchmidtandCopybara-Service 549e09cace Add FaceLandmarker iOS Live Stream API
PiperOrigin-RevId: 537434786
2023-06-02 16:22:20 -07:00
Sebastian SchmidtandCopybara-Service ace56b502a Add FaceLandmarker iOS API
PiperOrigin-RevId: 537424705
2023-06-02 15:35:48 -07:00
Sebastian SchmidtandCopybara-Service 5f50ac371f Internal
PiperOrigin-RevId: 537420663
2023-06-02 15:15:44 -07:00
Sebastian SchmidtandCopybara-Service 91a3c54d55 Internal change
PiperOrigin-RevId: 537405687
2023-06-02 14:12:35 -07:00
MediaPipe TeamandCopybara-Service b69f93fca6 Internal change
PiperOrigin-RevId: 537381138
2023-06-02 12:31:55 -07:00
Copybara-Service 09bad328ad Merge pull request #4485 from priankakariatyml:ios-delegate-fixes
PiperOrigin-RevId: 537369166
2023-06-02 11:49:18 -07:00
MediaPipe TeamandCopybara-Service 280bd320b4 Fix more OSS warnings and build errors
-Wc++98-compat-extra-semi
* in type_map.h

-Winconsistent-missing-override
* in gl_texture_buffer.h

-Wdeprecated-declarations
* usage of (absl) Status in
  * status_util.cc
  * api2/packet.h
  * output_stream_shard.cc

-Wimplicit-const-int-float-conversion
* Adds a static_cast to handle the precision loss when converting from large ints to floating point

ANNOTATE_THREAD_NAME
* explicitly uses ABSL_ANNOTATE_THREAD_NAME instead. This is useful in Chromium's build where there are multiple ANNOTATE_THREAD_NAME symbols

Also ran clang-format over all of each edited file

PiperOrigin-RevId: 537351290
2023-06-02 10:46:42 -07:00
MediaPipe TeamandCopybara-Service 9045a74ba3 Internal change
PiperOrigin-RevId: 537175065
2023-06-01 17:48:03 -07:00
Joe FernandezandCopybara-Service a6e63fa320 Adding redirects for old pages and updating pages for upgraded legacy solutions
PiperOrigin-RevId: 537145433
2023-06-01 15:31:42 -07:00
MediaPipe TeamandCopybara-Service 15aff443b1 Internal change
PiperOrigin-RevId: 537089863
2023-06-01 12:00:44 -07:00
Sebastian SchmidtandCopybara-Service 194a301dd8 Update WASM files for 0.10.1 release
PiperOrigin-RevId: 537078723
2023-06-01 11:22:40 -07:00
Prianka Liz Kariat 9356dfcd46 Updated MPPHandLandmarker.h to return the hand connections via class mathods 2023-06-01 16:53:32 +05:30
Prianka Liz Kariat e2f899e151 Updated documentation in MPPHandLandmarkResult+Helpers.h 2023-06-01 16:44:57 +05:30
Prianka Liz Kariat 961afc8928 Updated documentation in MPPHandLandmarkerResult Helpers 2023-06-01 16:43:33 +05:30
Paul WankadiaandCopybara-Service f21ee4c197 Update MediaPipe to RE2 release 2023-06-01.
Note that RE2 has taken a dependency on Abseil, so the `main` branch
should be used from now on. The `abseil` branch will go away soon...

PiperOrigin-RevId: 536829679
2023-05-31 14:52:24 -07:00
Prianka Liz Kariat 77bb5e7202 Fixed import in iOS gesture recognizer test utils 2023-05-31 20:53:36 +05:30
Prianka Liz Kariat ebeffc27eb Renamed iOS gesture recognizer protobuf utils 2023-05-31 20:51:43 +05:30
Prianka Liz Kariat 4326c97c95 Added MPPHandLandmark 2023-05-31 20:44:35 +05:30
Prianka Liz Kariat 0c33601510 Added MPPHandLandmarker 2023-05-31 20:44:25 +05:30
Prianka Liz Kariat ad499c170a Added MPPConnection 2023-05-31 20:43:24 +05:30
Prianka Liz Kariat 71f2f8f43b Added MPPHandLandmarkerResult Helpers 2023-05-31 20:42:49 +05:30
Prianka Liz Kariat 955489d71d Removed a test from iOS ObjC Gesture Recognizer tests 2023-05-31 20:39:01 +05:30
Prianka Liz Kariat e3b03866dc Removed unwanted import from MPPImageClassifier.h 2023-05-31 20:35:12 +05:30
Prianka Liz Kariat f77e685ff9 Removed unwanted header import from MPPGestureRecognizer.h 2023-05-31 20:34:02 +05:30
Prianka Liz Kariat c87e21206a Removed few test from MPPGestureRecognizerTests.m 2023-05-31 11:53:41 +05:30
Prianka Liz Kariat 365956807d Added gesture_recognizer.task to vision tasks test data 2023-05-31 11:52:29 +05:30
Prianka Liz Kariat 9546596b5a Updated variable name in MPPGestureRecognizerTests.m 2023-05-31 11:51:00 +05:30
Prianka Liz Kariat f3f664300c Added convenience method for creating results for tests in MPPGestureRecognizerResult Helpers 2023-05-31 11:50:39 +05:30
Prianka Liz Kariat 84560f3e7d Added more recognize tests to iOS Gesture Recognizer Objective C tests 2023-05-31 11:36:29 +05:30
Prianka Liz Kariat 1e77468eec Added iOS Gesture Recognizer ObjC Test for simple recognition 2023-05-31 11:29:37 +05:30
Prianka Liz Kariat 746f466c3a Added iOS Gesture Recognizer Protobuf utils 2023-05-31 11:28:50 +05:30
Sebastian SchmidtandCopybara-Service d76b48ec8b Add MP_DISABLE_GPU to .so target
PiperOrigin-RevId: 536537732
2023-05-30 16:18:02 -07:00
Copybara-Service 32e48dd2d9 Merge pull request #4486 from priankakariatyml:ios-gesture-recognizer-impl
PiperOrigin-RevId: 536516003
2023-05-30 14:53:04 -07:00
Sebastian SchmidtandCopybara-Service b7c940ef8a Internal change
PiperOrigin-RevId: 536499053
2023-05-30 13:51:06 -07:00
MediaPipe TeamandCopybara-Service 01cfb92e35 Add MultiLandmarksSmoothingCalculator
PiperOrigin-RevId: 536490704
2023-05-30 13:20:55 -07:00
MediaPipe TeamandCopybara-Service c73027926f Add MultiLandmarksSmoothingCalculator
PiperOrigin-RevId: 536478601
2023-05-30 12:37:05 -07:00
MediaPipe TeamandCopybara-Service a432559123 Port LandmarksSmoothingCalculator to api2
PiperOrigin-RevId: 536474279
2023-05-30 12:20:23 -07:00
Sebastian SchmidtandCopybara-Service 96357b1910 Internal change
PiperOrigin-RevId: 536457269
2023-05-30 11:21:17 -07:00
MediaPipe TeamandCopybara-Service 056881f4a9 Only apply face landmarks smoothing for stream mode (VIDEO and LIVE_STREAM).
PiperOrigin-RevId: 536455842
2023-05-30 11:16:43 -07:00
Prianka Liz Kariat aa7308498b Fixed typo 2023-05-30 23:38:04 +05:30
Copybara-Service fabde5f129 Merge pull request #4467 from priankakariatyml:ios-hand-landmarker-containers
PiperOrigin-RevId: 536447484
2023-05-30 10:49:22 -07:00
Copybara-Service 21eeac9fd7 Merge pull request #4464 from priankakariatyml:ios-gesture-recognizer-updates
PiperOrigin-RevId: 536421680
2023-05-30 09:24:06 -07:00
Prianka Liz Kariat b154dde19f Added iOS Gesture Recognizer implementation 2023-05-29 22:47:17 +05:30
Prianka Liz Kariat 6073d693d0 Added a method in iOS Object Detector to process packets for callbacks 2023-05-29 22:38:22 +05:30
Prianka Liz Kariat 250b11f5d1 Added a method in iOS image classifier to process result for the callback 2023-05-29 22:37:59 +05:30
MediaPipe TeamandCopybara-Service 759e9fd56e Reorganize the face stylizer test data.
PiperOrigin-RevId: 536074239
2023-05-28 19:28:14 -07:00
MediaPipe TeamandCopybara-Service 2e2b4d183e add “users” group to visibility
PiperOrigin-RevId: 536022725
2023-05-28 10:49:31 -07:00
MediaPipe TeamandCopybara-Service d4c7ed2217 Internal change
PiperOrigin-RevId: 535751178
2023-05-26 17:26:29 -07:00
Sebastian SchmidtandCopybara-Service fddc3facf0 Add FaceLandmarker Result API
PiperOrigin-RevId: 535735431
2023-05-26 16:04:47 -07:00
MediaPipe TeamandCopybara-Service e483b31fcf Internal change
PiperOrigin-RevId: 535636593
2023-05-26 09:23:37 -07:00
Prianka Liz Kariat 41d0f89fd1 Updated variable names in MPPHandLandmarkerOptionsHelpers 2023-05-26 21:06:29 +05:30
Prianka Liz Kariat 2428ba49a3 Fixed typo in MPPHandLandmarkerOptions 2023-05-26 21:02:14 +05:30
Prianka Liz Kariat 881c6e2eef Fixed typo in MPPHandLandmarkerResult 2023-05-26 21:00:59 +05:30
Prianka Liz Kariat bec7aeec22 Fixed typo in MPPHandLandmarkerOptions 2023-05-26 20:59:13 +05:30
Prianka Liz Kariat ff064e536c Added new line 2023-05-26 20:57:32 +05:30
Prianka Liz Kariat b442367fc9 Fixed formatting 2023-05-26 20:57:13 +05:30
Prianka Liz Kariat 23d97292a6 Updated face detector to use new methods from vision task runner 2023-05-26 18:49:24 +05:30
Prianka Liz Kariat 6fabc35ce7 Removed gesture recognizer implementation 2023-05-26 18:49:08 +05:30
Prianka Liz Kariat ddf4d3fbd3 Added iOS hand landmarker options helpers 2023-05-26 10:58:30 +05:30
Prianka Liz Kariat 5ad7c9fd89 Added iOS hand landmarker options 2023-05-26 10:58:12 +05:30
Prianka Liz Kariat f124cad095 Added iOS hand landmarker result 2023-05-26 10:57:58 +05:30
Copybara-Service f4337356fe Merge pull request #4465 from priankakariatyml:ios-landmark-test-cpp-utils
PiperOrigin-RevId: 535441782
2023-05-25 17:26:30 -07:00
MediaPipe TeamandCopybara-Service e2cb327060 Give an example of the expected protoType syntax
PiperOrigin-RevId: 535413303
2023-05-25 15:47:15 -07:00
MediaPipe TeamandCopybara-Service e8f2541cbd Internal update
PiperOrigin-RevId: 535376471
2023-05-25 14:03:43 -07:00
Jiuqiang TangandCopybara-Service 169bdf15b4 Make an option for adjusting the face alignment output image size, and add a "transformation_matrix" output stream of the face stylizer graph.
PiperOrigin-RevId: 535319310
2023-05-25 11:21:06 -07:00
MediaPipe TeamandCopybara-Service ea314ba455 Fix license typos.
PiperOrigin-RevId: 535309354
2023-05-25 10:53:37 -07:00
Sebastian SchmidtandCopybara-Service c7703bfb21 Add FaceLandmarkerOptions API
PiperOrigin-RevId: 535292669
2023-05-25 10:05:08 -07:00
Prianka Liz Kariat 1ec4ae44a5 Added C++ utils for parsing protos from text files for iOS tests. 2023-05-25 20:53:07 +05:30
Prianka Liz Kariat 52f3333cc1 Added MPPGesture Recognizer implementation 2023-05-25 20:44:16 +05:30
Prianka Liz Kariat e6fd39b3ee Updated the vision task runner to split the method that creates normalized rect based on ROI 2023-05-25 20:43:51 +05:30
Prianka Liz Kariat 9483ac4651 Updated iOS gesture recognizer results to initialize hand gestures with a default index 2023-05-25 20:42:24 +05:30
Khanh LeVietandCopybara-Service 952021f497 Remove unused MediaPipe Tasks Android sample
PiperOrigin-RevId: 535259478
2023-05-25 08:05:39 -07:00
MediaPipe TeamandCopybara-Service 3ac903787a Internal change
PiperOrigin-RevId: 535162357
2023-05-25 01:49:30 -07:00
Copybara-Service 034caf3d87 Merge pull request #4430 from kinaryml:python-gpu-support
PiperOrigin-RevId: 535133616
2023-05-24 23:53:00 -07:00
Sebastian SchmidtandCopybara-Service 1baf72e46b Internal change
PiperOrigin-RevId: 535131938
2023-05-24 23:45:16 -07:00
MediaPipe TeamandCopybara-Service 7800d238e9 add needed enum type for choose fuse pipeline.
PiperOrigin-RevId: 535076733
2023-05-24 20:17:54 -07:00
MediaPipe TeamandCopybara-Service c8ee09796b Internal change
PiperOrigin-RevId: 534959867
2023-05-24 13:26:53 -07:00
Copybara-Service b84e6f97dd Merge pull request #4456 from priankakariatyml:ios-code-review-fixes
PiperOrigin-RevId: 534957807
2023-05-24 13:22:31 -07:00
Sebastian SchmidtandCopybara-Service a7b81c7d10 Change "numberOfHands" property name to "numHands".
PiperOrigin-RevId: 534927982
2023-05-24 11:54:47 -07:00
Jiuqiang TangandCopybara-Service 7facc925ba Allow FaceStylizerGraph to miss base options.
Fix the color issue when the graph is running on gpu and "face alignment only" mode.

PiperOrigin-RevId: 534912498
2023-05-24 11:14:30 -07:00
Sebastian SchmidtandCopybara-Service acfaf3f1b6 Add unit test for FaceDetector iOS
PiperOrigin-RevId: 534874603
2023-05-24 09:40:08 -07:00
Sebastian SchmidtandCopybara-Service d9f316e12a Rename ObjectDetctionResult to ObjectDetectorResult
PiperOrigin-RevId: 534858600
2023-05-24 09:00:00 -07:00
Sebastian SchmidtandCopybara-Service 2017fcc9ab Add FaceDetector iOS API
PiperOrigin-RevId: 534858193
2023-05-24 08:55:03 -07:00
Prianka Liz Kariat 1aa44abcab Revert "Added support to set delegates in MPPBaseOptions"
This reverts commit 1e1693d9aa.
2023-05-24 20:25:45 +05:30
Prianka Liz Kariat 8f1a56f3c2 Fixed typos 2023-05-24 20:24:41 +05:30
Prianka Liz Kariat 1e1693d9aa Added support to set delegates in MPPBaseOptions 2023-05-24 20:24:34 +05:30
Prianka Liz Kariat e2e90dcac6 Merge branch 'master' into ios-code-review-fixes 2023-05-24 19:57:46 +05:30
Prianka Liz Kariat 69017381af Updated MPPObjectDetectorResult Helpers to return empty result instead of nil 2023-05-24 19:57:38 +05:30
MediaPipe TeamandCopybara-Service bc035d9146 This will fix the multiple typos in the tasks files.
PiperOrigin-RevId: 534679277
2023-05-23 21:49:34 -07:00
MediaPipe TeamandCopybara-Service 201b2d739d Fix c++98-compat-extra-semi warnings
PiperOrigin-RevId: 534624086
2023-05-23 18:03:29 -07:00
MediaPipe TeamandCopybara-Service 3dcfca3a73 Fix deprecated usages
* In status_builder.h to use absl::Status directly
* In type_map.h to use kTypeId.hash_code() directly

PiperOrigin-RevId: 534622923
2023-05-23 17:58:58 -07:00
Sebastian SchmidtandCopybara-Service e8ee934bf9 Use empty keypoint array for Detection if no keypoints are detected
PiperOrigin-RevId: 534572162
2023-05-23 15:10:00 -07:00
Copybara-Service 1523cc48a1 Merge pull request #4447 from priankakariatyml:ios-code-review-fixes
PiperOrigin-RevId: 534526451
2023-05-23 12:55:35 -07:00
Sebastian SchmidtandCopybara-Service 1fe78180c8 Add quality scores to Segmenter tasks
PiperOrigin-RevId: 534497957
2023-05-23 11:37:26 -07:00
Prianka Liz Kariat 3eb97ae1ff Updated Image classifier result to return empty results if packet can't be validated. 2023-05-23 20:54:42 +05:30
Prianka Liz Kariat fda001b666 Updated error tests to use XCTAssertEqualObjects 2023-05-23 19:31:14 +05:30
Sebastian SchmidtandCopybara-Service 87f525c76b Internal change
PiperOrigin-RevId: 534264040
2023-05-22 20:01:41 -07:00
Sebastian SchmidtandCopybara-Service 51730ec25c Add iOS support for MPMask
PiperOrigin-RevId: 534155657
2023-05-22 13:00:05 -07:00
MediaPipe TeamandCopybara-Service 102cffdf4c Add some helpful error messages in case GL texture creation fails.
PiperOrigin-RevId: 534029187
2023-05-22 05:03:51 -07:00
Sebastian SchmidtandCopybara-Service 7c28c5d58f Fix rendering of MPMask and MPImage clone
PiperOrigin-RevId: 533551170
2023-05-19 14:26:18 -07:00
Copybara-Service a6457d87b2 Merge pull request #4433 from priankakariatyml:ios-remove-delegate
PiperOrigin-RevId: 533472159
2023-05-19 09:24:26 -07:00
Copybara-Service 9044d62f61 Merge pull request #4422 from priankakariatyml:ios-gesture-recognizer-files
PiperOrigin-RevId: 533471803
2023-05-19 09:19:20 -07:00
Prianka Liz Kariat f219829b1d Removed support for Delegates from iOS 2023-05-19 17:42:57 +05:30
MediaPipe TeamandCopybara-Service 937a6b1422 Internal change
PiperOrigin-RevId: 533327411
2023-05-18 20:19:42 -07:00
MediaPipe TeamandCopybara-Service c248525eeb internal update
PiperOrigin-RevId: 533197055
2023-05-18 11:39:35 -07:00
MediaPipe TeamandCopybara-Service a1755044ea Internal change
PiperOrigin-RevId: 533187060
2023-05-18 11:10:42 -07:00
MediaPipe TeamandCopybara-Service 03b901a443 Internal change
PiperOrigin-RevId: 533150010
2023-05-18 09:16:35 -07:00
Kinar RandGitHub b5148c8ce3 Update setup.py 2023-05-18 18:32:45 +05:30
Kinar RandGitHub 01fdeaf1e1 Update Dockerfile 2023-05-18 18:29:22 +05:30
Kinar RandGitHub 6100f0e76e Update base_options.py 2023-05-18 18:09:39 +05:30
Kinar RandGitHub f63baaf8d2 Update BUILD 2023-05-18 18:08:04 +05:30
Kinar RandGitHub b5072c59e7 Update BUILD 2023-05-18 15:41:08 +05:30
Kinar RandGitHub 14dba421c4 Update BUILD 2023-05-18 13:23:44 +05:30
Kinar RandGitHub 620ff3508a Update BUILD 2023-05-18 12:51:08 +05:30
Kinar RandGitHub 126df20658 Included CPU binary graphs in setup.py 2023-05-18 11:00:12 +05:30
Prianka Liz Kariat bb5fcc2d64 Fixed Typos 2023-05-18 10:00:31 +05:30
Prianka Liz Kariat e905a9fe39 Removed roi methods from MPPGestureRecognizer 2023-05-18 09:52:23 +05:30
Rachel HornungandCopybara-Service 25458138a9 #MediaPipe Add ConcatenateStringVectorCalculator.
PiperOrigin-RevId: 532956844
2023-05-17 17:11:20 -07:00
MediaPipe TeamandCopybara-Service 02230f65d1 Internal change
PiperOrigin-RevId: 532934867
2023-05-17 15:54:32 -07:00
Sebastian SchmidtandCopybara-Service 1fb98f5ebd Don't double build ARM64 arch on M1 Macs
PiperOrigin-RevId: 532934646
2023-05-17 15:50:05 -07:00
Sebastian SchmidtandCopybara-Service a4d0e68bee Internal change
PiperOrigin-RevId: 532890317
2023-05-17 13:37:25 -07:00
Prianka Liz Kariat dc7c018b39 Added clearing of all graph options protos in MPPGestureRecognizerOptions Helpers 2023-05-17 22:03:10 +05:30
Prianka Liz Kariat d6d5a94845 Reverted copy of gesture recognizer result containers 2023-05-17 21:59:26 +05:30
Prianka Liz Kariat 36b7514b19 Removed srcs in MPPGestureRecognizer target 2023-05-17 21:56:31 +05:30
Prianka Liz Kariat dcb0414d4b Added MPPGestureRecognizer header 2023-05-17 21:53:25 +05:30
Prianka Liz Kariat 501b4bbc7b Added MPPGestureRecognizerResultHelpers 2023-05-17 21:52:05 +05:30
Prianka Liz Kariat ebd1545506 Added MPPGestureRecognizerOptionsHelpers 2023-05-17 21:51:40 +05:30
Prianka Liz Kariat a4c280310b Added delegates in iOS gesture recognizer options 2023-05-17 21:50:53 +05:30
Prianka Liz Kariat ae2901459d Updated property types in MPPGestureRecognizerResult 2023-05-17 21:50:11 +05:30
kinaryml 45addac249 Testing MediaPipe Python with GPU support 2023-05-17 10:55:40 +05:30
vrabaudandCopybara-Service 4f8520af10 Internal change
PiperOrigin-RevId: 532611846
2023-05-16 16:48:54 -07:00
MediaPipe TeamandCopybara-Service 5af496201b internal updating of flatbuffers
PiperOrigin-RevId: 532601578
2023-05-16 16:08:39 -07:00
MediaPipe TeamandCopybara-Service 609a57f167 Internal change
PiperOrigin-RevId: 532597768
2023-05-16 15:56:25 -07:00
Copybara-Service 7eb5cab22d Merge pull request #4397 from priankakariatyml:ios-remove-opencv-dep
PiperOrigin-RevId: 532553181
2023-05-16 13:15:53 -07:00
Sebastian SchmidtandCopybara-Service 024f782cd9 Warn users that do not invoke "close()"
PiperOrigin-RevId: 532507235
2023-05-16 10:50:38 -07:00
Sebastian SchmidtandCopybara-Service d53fbf2aeb Update links in README.md
PiperOrigin-RevId: 532506851
2023-05-16 10:45:30 -07:00
Sebastian SchmidtandCopybara-Service 8bf6c63e92 Write TFLite model to Wasm file system
PiperOrigin-RevId: 532482502
2023-05-16 09:25:44 -07:00
MediaPipe TeamandCopybara-Service d7fa4b95b5 Internal change.
PiperOrigin-RevId: 532474319
2023-05-16 08:56:30 -07:00
MediaPipe TeamandCopybara-Service e0eef9791e Internal change
PiperOrigin-RevId: 532113907
2023-05-15 08:06:33 -07:00
MediaPipe TeamandCopybara-Service fc9538533c Improve loop calculator documentation and add additional specializations
The documentation is confusing since it was unclear where e.g. BeginLoopWithIterableCalculator comes from. Also, input_to_loop_body wasn't connected to anything. loop_internal_ts is more confusing than helpful. This CL cleans up the docs. It also adds specializations for CPU image and GPU texture buffers to be used for the recompose effect.

PiperOrigin-RevId: 532083714
2023-05-15 05:58:58 -07:00
MediaPipe TeamandCopybara-Service 12ba644393 Internal change
PiperOrigin-RevId: 531582116
2023-05-12 12:57:28 -07:00
Copybara-Service c7ba201e6a Merge pull request #4372 from priankakariatyml:ios-image-classifier-async-fixes
PiperOrigin-RevId: 531517080
2023-05-12 08:50:14 -07:00
Copybara-Service 785f549130 Merge pull request #4401 from priankakariatyml:ios-typo-fixes
PiperOrigin-RevId: 531223233
2023-05-11 09:26:08 -07:00
Prianka Liz Kariat 4c32ff493e Fixed typo in MPPObjectDetectorOptions 2023-05-11 14:04:40 +05:30
MediaPipe TeamandCopybara-Service 64af919107 Internal change
PiperOrigin-RevId: 531007009
2023-05-10 14:38:19 -07:00
Sebastian SchmidtandCopybara-Service 1666f3ed80 Add .close() method to ImageSegmenterResult/InteractiveSegmenterResult/PoseLandmarkerResult
PiperOrigin-RevId: 530973944
2023-05-10 12:37:48 -07:00
Prianka Liz Kariat 419701c615 Removed opencv dependency from MPPVIsionTaskRunner 2023-05-10 13:09:44 +05:30
Mark McDonaldandCopybara-Service a7ede9235c Internal change
PiperOrigin-RevId: 530806084
2023-05-09 22:34:07 -07:00
MediaPipe TeamandCopybara-Service ea1643f7f8 Internal update
PiperOrigin-RevId: 530777692
2023-05-09 19:47:43 -07:00
MediaPipe TeamandCopybara-Service f824424700 When returning multiple output streams together, keep them alive until callback.
PiperOrigin-RevId: 530771884
2023-05-09 19:00:00 -07:00
MediaPipe TeamandCopybara-Service e391c76433 Include object_detector_metadata_schema.fbs and image_segmenter_metadata_schema.fbs
PiperOrigin-RevId: 530769920
2023-05-09 18:45:01 -07:00
MediaPipe Teamandjqtang f95a782399 Internal change
PiperOrigin-RevId: 530751565
2023-05-09 17:03:20 -07:00
MediaPipe TeamandCopybara-Service 6ff39c418c Internal change
PiperOrigin-RevId: 530751097
2023-05-09 17:01:45 -07:00
MediaPipe TeamandCopybara-Service dd1779840d Update model_maker requirements.txt for release
PiperOrigin-RevId: 530748415
2023-05-09 16:49:41 -07:00
Sebastian SchmidtandGitHub a469f0151b Merge pull request #4386 from priankakariatyml/ios-cocoapods-opencv-fixes
Removed opencv framework from MPPVisionTaskRunner dependendencies
2023-05-09 17:08:32 -06:00
MediaPipe TeamandCopybara-Service f77481f303 MediaPipe GPU: Log renderer.
We currently log GL version, but since we support multiple backends, logging the renderer as well takes away any doubt what is being used at runtime.

PiperOrigin-RevId: 530736209
2023-05-09 15:57:31 -07:00
Sebastian SchmidtandCopybara-Service bea5eb766d Move Java Connections arrays to Task class
PiperOrigin-RevId: 530719994
2023-05-09 14:52:33 -07:00
Sebastian SchmidtandCopybara-Service 6f3c80ae8a Prevent property mangling for options types
PiperOrigin-RevId: 530707361
2023-05-09 14:05:05 -07:00
Jiuqiang TangandCopybara-Service 05c565898a Add image_segmenter_metadata_schema and object_detector_metadata_schema python files to the mediapipe python wheels.
PiperOrigin-RevId: 530674961
2023-05-09 12:02:31 -07:00
MediaPipe TeamandCopybara-Service 08d19739e0 Allow passing --resource_root_dir to resolve asset lookups.
PiperOrigin-RevId: 530618235
2023-05-09 08:40:11 -07:00
MediaPipe TeamandCopybara-Service 9de52a4a30 Internal change
PiperOrigin-RevId: 530562491
2023-05-09 03:48:49 -07:00
Prianka Liz Kariat 99e3d355cb Removed opencv framework dep from MPPVisionTaskRunner deps 2023-05-09 11:28:19 +05:30
MediaPipe TeamandCopybara-Service 10776ef86f Added error message if no provisioning profile found
PiperOrigin-RevId: 530498369
2023-05-08 22:20:19 -07:00
Sebastian SchmidtandCopybara-Service 65cb5f4e6b Do not depend on *.ts files in ts_declaration
PiperOrigin-RevId: 530435849
2023-05-08 16:20:18 -07:00
Copybara-Service ee8d0383d6 Merge pull request #4380 from priankakariatyml:ios-cocoapods-fixes
PiperOrigin-RevId: 530409793
2023-05-08 14:35:09 -07:00
MediaPipe TeamandCopybara-Service 83a8743a8b Internal change
PiperOrigin-RevId: 530408554
2023-05-08 14:31:04 -07:00
MediaPipe TeamandCopybara-Service b40f0d3b72 Internal change
PiperOrigin-RevId: 530385895
2023-05-08 13:04:51 -07:00
Sebastian SchmidtandCopybara-Service ae8bedd352 Inline constants for FaceLandmarksConnections
PiperOrigin-RevId: 530384171
2023-05-08 12:58:18 -07:00
Sebastian SchmidtandCopybara-Service e3c2f31ddf Update WASM files for Alpha 14
PiperOrigin-RevId: 530341569
2023-05-08 10:31:46 -07:00
Shuang LiuandCopybara-Service 0c75c76623 Fix a typo.
PiperOrigin-RevId: 530339315
2023-05-08 10:24:29 -07:00
Prianka Liz Kariat 4a192a6d87 Updated formatting in MPPImageClassifier 2023-05-08 16:58:00 +05:30
Prianka Liz Kariat db732e2913 Updated formatting in MPPImageClassifierOptions 2023-05-08 16:57:17 +05:30
Prianka Liz Kariat 443418f6d5 Updated formatting 2023-05-08 16:45:16 +05:30
Prianka Liz Kariat 946042aca1 Reverted addition of flow limiter calculator in image classifier iOS 2023-05-08 16:33:09 +05:30
Prianka Liz Kariat 1865643486 Fixed deps in ios task BUILD file 2023-05-08 16:32:04 +05:30
Prianka Liz Kariat 26810b6b84 Reverted back to using containers and options in BUILD 2023-05-08 16:30:40 +05:30
Prianka Liz Kariat f86188f8e1 Merged with master 2023-05-08 16:24:54 +05:30
Copybara-Service 1360977730 Merge pull request #4373 from priankakariatyml:ios-object-detector-async-fixes
PiperOrigin-RevId: 530233608
2023-05-08 01:14:01 -07:00
MediaPipe TeamandCopybara-Service 613f645c74 Update CalculatorOptions to encourage proto3 options
PiperOrigin-RevId: 530127533
2023-05-07 11:25:43 -07:00
MediaPipe TeamandCopybara-Service 876987b389 Remove auxiliary landmarks in PoseLandmarker API results.
PiperOrigin-RevId: 529989746
2023-05-06 12:58:00 -07:00
Sebastian SchmidtandCopybara-Service ddb84702f6 Simplify MPMask by removing the Type Enums from the public API
PiperOrigin-RevId: 529975377
2023-05-06 10:26:13 -07:00
Sebastian SchmidtandCopybara-Service e9fc66277a Simplify MPImage API by removing the Type Enums from the public API
PiperOrigin-RevId: 529960399
2023-05-06 07:49:46 -07:00
Sebastian SchmidtandCopybara-Service 8a6fe90759 Remove single-channel types from MPImage
PiperOrigin-RevId: 529956549
2023-05-06 07:04:14 -07:00
MediaPipe TeamandCopybara-Service 800a7b4a27 Object detector handle empty packet when no object is detected.
PiperOrigin-RevId: 529919638
2023-05-06 01:11:01 -07:00
MediaPipe TeamandCopybara-Service cc8847def5 Update one-class segmentation category mask behavior on CPU to match latest API
PiperOrigin-RevId: 529917830
2023-05-06 00:55:26 -07:00
Sebastian SchmidtandCopybara-Service fb7f06b509 Remove error check that canvas must be defined
PiperOrigin-RevId: 529906685
2023-05-05 23:22:40 -07:00
Sebastian SchmidtandCopybara-Service 6aad5742c3 Internal
PiperOrigin-RevId: 529890599
2023-05-05 21:51:51 -07:00
Sebastian SchmidtandCopybara-Service e707c84a3d Create a MediaPipe Mask Type
PiperOrigin-RevId: 529868427
2023-05-05 19:23:43 -07:00
Prianka Liz Kariat f713be7b6d Updated deps names in iOS test targets 2023-05-06 06:13:51 +05:30
MediaPipe TeamandCopybara-Service 3562a7f7dc Update one-class segmentation category mask behavior on GPU to match latest API
PiperOrigin-RevId: 529853658
2023-05-05 17:32:06 -07:00
Prianka Liz Kariat 9f0dd03851 Updated comments 2023-05-06 05:15:23 +05:30
Prianka Liz Kariat d79c0bbd39 Updated formatting 2023-05-06 05:10:05 +05:30
Prianka Liz Kariat 72d6081263 Declared arrays for duplicate depepndencies 2023-05-06 04:59:19 +05:30
Prianka Liz Kariat 648a24a97b Added conditional building of opencv xc framework to test targets 2023-05-06 04:58:59 +05:30
Prianka Liz Kariat 4349ac48b0 Changed opencv framework version to 4.5.3 2023-05-06 04:39:09 +05:30
Prianka Liz Kariat d22a1318f6 Updated condition checks in third_party/BUILD 2023-05-06 04:37:09 +05:30
Prianka Liz Kariat 26fce393e8 Removed opencv framework target from vision runner deps 2023-05-06 04:36:49 +05:30
Prianka Liz Kariat 1daf4d74ee Updated common dependencies to link in helpers 2023-05-06 04:35:51 +05:30
Prianka Liz Kariat 6427c49d2d Aded version of dependency to podspec template 2023-05-06 04:25:24 +05:30
Prianka Liz Kariat 78224aaee6 Updated shell script to build ios opencv from source 2023-05-06 04:24:36 +05:30
Prianka Liz Kariat 2fa03a3699 Added flow limiter calculator and conditionally selected xcframework in iOS framework targets 2023-05-06 04:23:49 +05:30
Sebastian SchmidtandCopybara-Service f6d0a5e03a Make the timestamp the second argument in all xForVideo() methods
PiperOrigin-RevId: 529814792
2023-05-05 14:29:33 -07:00
Copybara-Service 13187208ac Merge pull request #4355 from priankakariatyml:ios-opencv-build-from-source
PiperOrigin-RevId: 529800547
2023-05-05 13:34:46 -07:00
Sebastian SchmidtandCopybara-Service f065910559 Create non-callback APIs for APIs that return callbacks.
PiperOrigin-RevId: 529799515
2023-05-05 13:30:36 -07:00
MediaPipe TeamandCopybara-Service ecc8dca8ba Internal change
PiperOrigin-RevId: 529752098
2023-05-05 10:28:38 -07:00
MediaPipe TeamandCopybara-Service c24e7a250c Internal change
PiperOrigin-RevId: 529617578
2023-05-04 23:01:32 -07:00
Sebastian SchmidtandCopybara-Service 18d893c697 Add scribble support to InteractiveSegmenter Web API
PiperOrigin-RevId: 529594131
2023-05-04 20:44:26 -07:00
MediaPipe TeamandCopybara-Service 61cfe2ca9b Object Detector remove nms operation from exported tflite
PiperOrigin-RevId: 529559380
2023-05-04 17:36:11 -07:00
MediaPipe Teamandjqtang 12b0b6fad1 Internal change
PiperOrigin-RevId: 529495239
2023-05-04 14:51:19 -07:00
Prianka Liz Kariat 1db1c29f50 Added code comments 2023-05-05 01:04:04 +05:30
Prianka Liz Kariat 330976ce9e Added utils of containers and core to MPPTaskCommon to avoid warnings in xcode 2023-05-04 23:51:41 +05:30
Prianka Liz Kariat 47013d289e Added flow limiter calculator in MediaPipeTasksCommon 2023-05-04 23:19:12 +05:30
MediaPipe TeamandCopybara-Service 64cad80543 Internal change.
PiperOrigin-RevId: 529449175
2023-05-04 10:33:40 -07:00
Prianka Liz Kariat 253662149e Updated pixel format types in object detector 2023-05-04 23:03:03 +05:30
Sebastian SchmidtandCopybara-Service 767db32d69 Support multiple poses for PoseLandmarker
PiperOrigin-RevId: 529430797
2023-05-04 09:29:12 -07:00
Prianka Liz Kariat 3df4f7db64 Updated time out for object detector 2023-05-04 20:00:29 +05:30
Prianka Liz Kariat 08282d9fd7 Updated time out for image classifier async tests 2023-05-04 19:59:39 +05:30
Prianka Liz Kariat a4e11eac78 Added constants for time out 2023-05-04 19:55:19 +05:30
Prianka Liz Kariat 00712d727e Updated wait time for object detector tests 2023-05-04 19:53:06 +05:30
Prianka Liz Kariat 33ae23c53a Increased wait time for image classifier asynchronous tests 2023-05-04 19:51:54 +05:30
Prianka Liz Kariat 8ec0724b65 Updated documentation to include note about rgba images 2023-05-04 19:44:11 +05:30
Prianka Liz Kariat ddd1515f88 Updated documentation 2023-05-04 19:40:15 +05:30
Prianka Liz Kariat d401439daa Updated formatting 2023-05-04 19:22:11 +05:30
Prianka Liz Kariat 1136d4d515 Updated CVPixelBuffer to support pixel format type of 32RGBA 2023-05-04 18:58:49 +05:30
Prianka Liz Kariat 7a7f27c34b Merge branch 'ios-normalized-keypoint-hash' into ios-object-detector-async-fixes 2023-05-04 17:21:36 +05:30
Prianka Liz Kariat 381ffcb474 Added hash implementation for iOS normalized keypoint 2023-05-04 17:10:07 +05:30
Prianka Liz Kariat 87593a2ade Updated docuemntation of MPPObjectDetector 2023-05-04 17:05:17 +05:30
Prianka Liz Kariat ab135190e5 Updated iOS object detector to use delegates instead of callbacks for async calls 2023-05-04 17:03:40 +05:30
Prianka Liz Kariat a21c08bf4d Added method for creating unique dispatch queue names in MPPVisionTaskRunner 2023-05-04 17:00:12 +05:30
Prianka Liz Kariat e47bb16544 Added validation of C++ image classification result packet in MPPImageClassifierResult+Helpers.mm 2023-05-04 16:52:58 +05:30
Prianka Liz Kariat ab4b07646c Updated MPPImageClassifier to use delegates instead of completion blocks for callback. 2023-05-04 16:43:18 +05:30
Prianka Liz Kariat 1323a5271c Added method to create unique dispatch queue names in MPPVisionTaskRunner 2023-05-04 16:39:43 +05:30
Jiuqiang TangandCopybara-Service c6e3f08282 Expose FaceAligner and LanguageDetector to be public MediaPipe Tasks Python API.
PiperOrigin-RevId: 529227382
2023-05-03 16:38:49 -07:00
MediaPipe TeamandCopybara-Service b350f72394 Support MultiHW AVG Architecture for object detector
PiperOrigin-RevId: 529221127
2023-05-03 16:12:59 -07:00
Copybara-Service 8c324fbd77 Merge pull request #4325 from kinaryml:language-detector-python
PiperOrigin-RevId: 529213966
2023-05-03 15:50:42 -07:00
MediaPipe TeamandCopybara-Service a09e39d431 Add TransformerParameters proto
PiperOrigin-RevId: 529213840
2023-05-03 15:46:50 -07:00
Yuqi LiandCopybara-Service e428bdb7e8 internal change.
PiperOrigin-RevId: 529181374
2023-05-03 13:37:16 -07:00
MediaPipe TeamandCopybara-Service 606b83ac65 Internal change
PiperOrigin-RevId: 529180655
2023-05-03 13:32:44 -07:00
MediaPipe TeamandCopybara-Service 7c955246aa Support scribble input for Interactive Segmenter Java API
PiperOrigin-RevId: 529177660
2023-05-03 13:22:09 -07:00
Copybara-Service e84e90e5b2 Merge pull request #4361 from kinaryml:face-aligner-python
PiperOrigin-RevId: 529165597
2023-05-03 12:39:23 -07:00
MediaPipe TeamandCopybara-Service c780559214 Internal change
PiperOrigin-RevId: 529161249
2023-05-03 12:20:44 -07:00
MediaPipe TeamandCopybara-Service 09662749ea Support scribble input for Interactive Segmenter
PiperOrigin-RevId: 529156049
2023-05-03 12:01:10 -07:00
MediaPipe TeamandCopybara-Service baa8fc68a1 Make uploading to GPU optional in Image.GetGpuBuffer().
PiperOrigin-RevId: 529066617
2023-05-03 05:57:58 -07:00
MediaPipe TeamandCopybara-Service 3789156a41 Internal change
PiperOrigin-RevId: 529011480
2023-05-03 00:29:13 -07:00
MediaPipe TeamandCopybara-Service 1dea01aecc Internal change
PiperOrigin-RevId: 528996603
2023-05-02 22:57:38 -07:00
MediaPipe TeamandCopybara-Service c698381e48 Internal change
PiperOrigin-RevId: 528939095
2023-05-02 18:05:31 -07:00
Jiuqiang TangandCopybara-Service bf11fb313e Expose PoseLandmarker as a public MediaPipe Tasks Python API.
PiperOrigin-RevId: 528882303
2023-05-02 14:04:01 -07:00
Jiuqiang TangandCopybara-Service 4d9812af43 Pose detector uses advanced_gpu_api for gpu inference to resolve unsupported gpu op issue.
PiperOrigin-RevId: 528879218
2023-05-02 13:52:26 -07:00
Yuqi LiandCopybara-Service 9ce16fddeb nit: format the documentation of LandmarksDetectionResult.
PiperOrigin-RevId: 528848566
2023-05-02 11:56:47 -07:00
MediaPipe TeamandCopybara-Service 421c9e8e97 Fix typo
PiperOrigin-RevId: 528829423
2023-05-02 10:51:47 -07:00
MediaPipe TeamandCopybara-Service 4d112c132f Fix msan errors.
PiperOrigin-RevId: 528825081
2023-05-02 10:37:50 -07:00
Jiuqiang TangandCopybara-Service 60055f6fee Add more comments and usage example of the face stylizer graph.
PiperOrigin-RevId: 528823127
2023-05-02 10:32:43 -07:00
MediaPipe TeamandCopybara-Service 7fdbbee5be Internal change
PiperOrigin-RevId: 528799585
2023-05-02 09:07:29 -07:00
MediaPipe TeamandCopybara-Service 5b93477589 internal change
PiperOrigin-RevId: 528719459
2023-05-02 02:17:18 -07:00
Chuo-Ling ChangandCopybara-Service 3719aaef7e Fix typo.
PiperOrigin-RevId: 528693117
2023-05-01 23:52:45 -07:00
MediaPipe TeamandCopybara-Service 0a8be0d09d Internal change
PiperOrigin-RevId: 528632873
2023-05-01 18:40:33 -07:00
Jiuqiang TangandCopybara-Service fca728d226 Set face alignment image width and hight to 256.
PiperOrigin-RevId: 528583074
2023-05-01 15:01:39 -07:00
Jiuqiang TangandCopybara-Service 162a999887 Check the output stream tag rather than the input stream tag in face stylizer graph.
PiperOrigin-RevId: 528555024
2023-05-01 13:14:32 -07:00
MediaPipe TeamandCopybara-Service 5526e96b21 Internal change for proto library outputs.
PiperOrigin-RevId: 528539840
2023-05-01 12:17:29 -07:00
Yuqi LiandCopybara-Service 085f8265fb Internal change
PiperOrigin-RevId: 528517562
2023-05-01 11:01:23 -07:00
Kinar RandGitHub 544e4b66f7 Merge branch 'google:master' into face-aligner-python 2023-05-01 22:56:00 +05:30
MediaPipe TeamandCopybara-Service cab619f8da Fix typo in README
PiperOrigin-RevId: 528506206
2023-05-01 10:25:05 -07:00
Jiuqiang TangandCopybara-Service b9a9da5de5 Ignore fetching face stylizer model when the graph doesn't output stylized face images.
PiperOrigin-RevId: 528504312
2023-05-01 10:18:41 -07:00
kinaryml bd039f8b65 Updated necessary BUILD files 2023-05-01 05:56:52 -07:00
kinaryml 209d78f36c Added the Face Aligner Python API 2023-05-01 05:55:46 -07:00
MediaPipe TeamandCopybara-Service ad4ae6559b Add an extra op to rescale face stylizer generation output from [-1, 1] to [0, 1].
This conversion is to support running the model on both GPU and CPU.

PiperOrigin-RevId: 528400297
2023-04-30 23:14:29 -07:00
MediaPipe TeamandCopybara-Service 80b19fff4b Internal Change
PiperOrigin-RevId: 528399911
2023-04-30 23:10:21 -07:00
Jiuqiang TangandCopybara-Service c29e43dda0 Add the "FACE_ALIGNMENT" output stream to the face stylizer graph.
PiperOrigin-RevId: 528345204
2023-04-30 16:59:36 -07:00
MediaPipe TeamandCopybara-Service c450283715 Add a filegroup for referencing model.
PiperOrigin-RevId: 528251316
2023-04-30 01:19:19 -07:00
Sebastian SchmidtandCopybara-Service 8e510a3255 Invoke PoseListener callback while C++ Packet is still active
PiperOrigin-RevId: 528061429
2023-04-28 21:22:02 -07:00
Sebastian SchmidtandCopybara-Service 253f13ad62 Invoke callback for InteractiveSegmenter while C++ Packets are active
PiperOrigin-RevId: 528053621
2023-04-28 20:34:17 -07:00
Sebastian SchmidtandCopybara-Service d5c5457d25 Only log warnings once if color conversion is not specified
PiperOrigin-RevId: 528052009
2023-04-28 20:24:17 -07:00
Sebastian SchmidtandCopybara-Service a9721ae2fb Invoke callback for ImageSegmenter while C++ Packets are active
PiperOrigin-RevId: 528047220
2023-04-28 20:01:10 -07:00
Sebastian SchmidtandCopybara-Service e15add2475 Shorten MPImage API
PiperOrigin-RevId: 528039371
2023-04-28 19:00:17 -07:00
Esha UbowejaandCopybara-Service b1f93b3b27 Fixes HAND_ROIS_FROM_LANDMARKS output to be hand_rects_from_landmarks output stream.
PiperOrigin-RevId: 528024796
2023-04-28 17:25:05 -07:00
Sebastian SchmidtandCopybara-Service 874cc9dea3 Update PoseLandmarker to return MPImage
PiperOrigin-RevId: 528022223
2023-04-28 17:13:07 -07:00
Sebastian SchmidtandCopybara-Service dcef6df1cb Update InteractiveSegmenter to return MPImage
PiperOrigin-RevId: 528010944
2023-04-28 16:13:51 -07:00
Copybara-Service bbbc0f98c5 Merge pull request #4268 from priankakariatyml:object-detector-objc-tests
PiperOrigin-RevId: 527991967
2023-04-28 14:52:20 -07:00
Sebastian SchmidtandCopybara-Service 2c1d9c6582 Update ImageSegmenter to return MPImage
PiperOrigin-RevId: 527990991
2023-04-28 14:48:30 -07:00
Sebastian SchmidtandCopybara-Service a544098100 Update FaceStylizer to return MPImage
PiperOrigin-RevId: 527980696
2023-04-28 14:05:11 -07:00
Copybara-Service 5cffb3973f Merge pull request #4303 from kinaryml:pose-landmarker-python
PiperOrigin-RevId: 527948047
2023-04-28 11:59:28 -07:00
Copybara-Service 2bb1b454ea Merge pull request #4300 from priankakariatyml:ios-text-cocoapods-force-load
PiperOrigin-RevId: 527932547
2023-04-28 11:06:44 -07:00
MediaPipe TeamandCopybara-Service 3dce259bf6 Internal change
PiperOrigin-RevId: 527931585
2023-04-28 11:02:26 -07:00
MediaPipe TeamandCopybara-Service b2fbb2ddab Internal change
PiperOrigin-RevId: 527909361
2023-04-28 09:43:56 -07:00
MediaPipe TeamandCopybara-Service cf22c97143 Add the TFLite conversion API to BlazeFaceStylizer in model maker.
PiperOrigin-RevId: 527806005
2023-04-28 00:30:51 -07:00
kinaryml 3b06772d9a Fixed BUILD 2023-04-27 21:13:31 -07:00
kinaryml 305866ccae Updated BUILD files to use the open sourced Language Detector model 2023-04-27 21:11:53 -07:00
Kinar RandGitHub 76c8251faf Merge branch 'google:master' into language-detector-python 2023-04-28 09:28:54 +05:30
Sebastian SchmidtandCopybara-Service 5d9761cbfd Update tests and demos to call "close".
PiperOrigin-RevId: 527746909
2023-04-27 18:58:57 -07:00
Sebastian SchmidtandCopybara-Service 28b9b8d8a3 Open-sources LanguageDetector model.
PiperOrigin-RevId: 527745108
2023-04-27 18:47:07 -07:00
Sebastian SchmidtandCopybara-Service 5e41d47f3a Add "close()" method to MP Web Tasks
PiperOrigin-RevId: 527726737
2023-04-27 17:16:40 -07:00
Sebastian SchmidtandCopybara-Service b7e46ec528 Update WASM files for Alpha 13
PiperOrigin-RevId: 527707613
2023-04-27 15:58:03 -07:00
Prianka Liz Kariat 82840b8e28 Removed comments 2023-04-28 03:30:47 +05:30
Prianka Liz Kariat fec11735a3 Updated formatting 2023-04-28 03:30:21 +05:30
Prianka Liz Kariat bdede4f94e Updated select conditions 2023-04-28 03:26:29 +05:30
Prianka Liz Kariat aafb0162f4 Added config settings to select building iOS xcframework from source for certain configs 2023-04-28 03:17:22 +05:30
Prianka Liz Kariat ad4513784c Added build file for ios opencv from sources 2023-04-28 03:16:08 +05:30
Prianka Liz Kariat 2a0aa86ca9 Added http_archive to download opencv sources 2023-04-28 03:14:41 +05:30
Prianka Liz Kariat 8e82e91095 Added config for fat simulator builds 2023-04-28 03:13:14 +05:30
Sebastian SchmidtandCopybara-Service 4e1270c18f Internal
PiperOrigin-RevId: 527680530
2023-04-27 14:14:54 -07:00
MediaPipe TeamandCopybara-Service 212f110c65 Add nose in facemesh drawing
PiperOrigin-RevId: 527644154
2023-04-27 12:00:37 -07:00
MediaPipe TeamandCopybara-Service 3ca2427cc8 Blendshapes graph take smoothed face landmarks as input.
PiperOrigin-RevId: 527640341
2023-04-27 11:46:40 -07:00
MediaPipe TeamandCopybara-Service 82b8e4d7bf Update the face stylizer config to match the latest encoder and detector config.
PiperOrigin-RevId: 527637477
2023-04-27 11:37:16 -07:00
Copybara-Service 4fd77e38fb Merge pull request #4269 from shmishra99:master
PiperOrigin-RevId: 527634460
2023-04-27 11:27:15 -07:00
Sebastian SchmidtandCopybara-Service 1b82821f15 Add support for single-channel images to MPImage
PiperOrigin-RevId: 527629970
2023-04-27 11:12:34 -07:00
Sebastian SchmidtandCopybara-Service a5852b0513 Internal change
PiperOrigin-RevId: 527623223
2023-04-27 10:50:36 -07:00
Copybara-Service cd47080057 Merge pull request #4351 from kuaashish:master
PiperOrigin-RevId: 527619288
2023-04-27 10:37:23 -07:00
Sebastian SchmidtandCopybara-Service d5157a039e Add .github workspace import
PiperOrigin-RevId: 527617546
2023-04-27 10:31:44 -07:00
Sebastian SchmidtandCopybara-Service b457060c3a Generify tests for MPImage
PiperOrigin-RevId: 527611864
2023-04-27 10:12:30 -07:00
Sebastian SchmidtandCopybara-Service bc3434108e Update MPImage to use containers
PiperOrigin-RevId: 527596164
2023-04-27 09:18:05 -07:00
Jiuqiang TangandCopybara-Service 7c70c62465 Fix typo and improve comments.
PiperOrigin-RevId: 527580369
2023-04-27 08:10:29 -07:00
MediaPipe TeamandCopybara-Service 7b055df211 Internal change
PiperOrigin-RevId: 527473249
2023-04-26 22:14:32 -07:00
MediaPipe TeamandCopybara-Service 2122b5d7be Internal change
PiperOrigin-RevId: 527430483
2023-04-26 18:17:56 -07:00
MediaPipe TeamandCopybara-Service b05fd21709 Refactor the loss functions to initialize the VGG loss function in the init function to avoid duplicated initialization.
PiperOrigin-RevId: 527424556
2023-04-26 17:49:19 -07:00
MediaPipe TeamandCopybara-Service baed44ab10 Internal change
PiperOrigin-RevId: 527416263
2023-04-26 17:12:34 -07:00
MediaPipe TeamandCopybara-Service a45d1f5e90 Internal change.
PiperOrigin-RevId: 527374728
2023-04-26 14:27:58 -07:00
Prianka Liz Kariat 261e02e491 Fixed case name 2023-04-27 02:55:58 +05:30
Prianka Liz Kariat ee2665ad13 Added missing input files in vision library 2023-04-27 02:54:50 +05:30
Prianka Liz Kariat 1d8e24b9aa Updated documentation 2023-04-27 02:47:52 +05:30
Prianka Liz Kariat a8cb1f1dad Updated default values 2023-04-27 02:47:19 +05:30
Prianka Liz Kariat 1e776e8e01 Fixed indendation issues 2023-04-27 02:31:30 +05:30
Prianka Liz Kariat 9c98435027 Updated iOS framework names 2023-04-27 02:15:16 +05:30
MediaPipe TeamandCopybara-Service c44cc30ece DetectionPostProcessingGraph for post processing raw tensors from detection models.
PiperOrigin-RevId: 527363291
2023-04-26 13:44:54 -07:00
MediaPipe TeamandCopybara-Service 48aa88f39d Change object detector learning rate decay to cosine decay.
PiperOrigin-RevId: 527337105
2023-04-26 12:13:17 -07:00
kuaashishandGitHub 6f97203562 Rename 18-other-issues.md to 19-other-issues.md 2023-04-26 16:38:23 +05:30
kuaashishandGitHub 5f505b09e3 Rename 17-solution-legacy-issue-template.yaml to 18-solution-legacy-issue-template.yaml 2023-04-26 16:38:05 +05:30
kuaashishandGitHub 275eb31a8f Rename 16-documentation-issue-template.yaml to 17-documentation-issue-template.yaml 2023-04-26 16:37:44 +05:30
kuaashishandGitHub f9d14157ff Rename 15-bug-issue-template.yaml to 16-bug-issue-template.yaml 2023-04-26 16:37:28 +05:30
kuaashishandGitHub 9c8fe490d4 Rename 14-build-install-issue-template.yaml to 15-build-install-issue-template.yaml 2023-04-26 16:36:58 +05:30
kuaashishandGitHub f36f2c64b5 Rename 16-feature-request-issue-template.yaml to 14-feature-request-issue-template.yaml 2023-04-26 16:36:33 +05:30
kuaashishandGitHub d6b4067319 Rename 15-feature-request-issue-template.yaml to 16-feature-request-issue-template.yaml 2023-04-26 16:35:44 +05:30
kuaashishandGitHub 7d6ccb2dd1 Rename 14-feature-request-issue-template.yaml to 15-feature-request-issue-template.yaml 2023-04-26 16:35:16 +05:30
kuaashishandGitHub 728cb26644 Rename 13-feature-request-issue-template.yaml to 14-feature-request-issue-template.yaml 2023-04-26 16:34:48 +05:30
kuaashishandGitHub 4046b97416 Rename 50-other-issues.md to 18-other-issues.md 2023-04-26 16:32:41 +05:30
kuaashishandGitHub 00f355e301 Rename Solution(Legacy_issue_template).yaml to 17-solution-legacy-issue-template.yaml 2023-04-26 16:32:06 +05:30
kuaashishandGitHub a002e24080 Rename Documentation_issue_template.yaml to 16-documentation-issue-template.yaml 2023-04-26 16:31:16 +05:30
kuaashishandGitHub d15701a5e0 Rename bug_issue_template.yaml to 15-bug-issue-template.yaml 2023-04-26 16:30:46 +05:30
kuaashishandGitHub a99b0d6b9c Rename build.install_issue_template.yaml to 14-build-install-issue-template.yaml 2023-04-26 16:30:23 +05:30
kuaashishandGitHub badccdd87b Rename feature_request_issue_template.yaml to 13-feature-request-issue-template.yaml 2023-04-26 16:29:49 +05:30
kuaashishandGitHub 2d69c48e39 Rename studio_issue_template.yaml to 12-studio-issue-template.yaml 2023-04-26 16:27:12 +05:30
kuaashishandGitHub 17bee87b27 Rename model_maker_issue_template.yaml to 11-model-maker-issue-template.yaml 2023-04-26 16:26:39 +05:30
kuaashishandGitHub db2592a04d Rename task_issue_template.yaml to 00-task-issue-template.yaml 2023-04-26 16:24:20 +05:30
MediaPipe TeamandCopybara-Service 507ed0d91d Add custom metadata for object detection model with out-of-graph nms.
PiperOrigin-RevId: 527083453
2023-04-25 14:58:51 -07:00
MediaPipe TeamandCopybara-Service 17f5b95387 Internal change.
PiperOrigin-RevId: 527010360
2023-04-25 10:41:52 -07:00
Sebastian SchmidtandCopybara-Service 9e30b00685 Invoke the FaceStylizer callback even if no faces are detected
PiperOrigin-RevId: 527008261
2023-04-25 10:35:12 -07:00
Jiuqiang TangandCopybara-Service 3bc8276678 Remove "All Rights Reserved." in copyright headers.
PiperOrigin-RevId: 526982992
2023-04-25 09:06:29 -07:00
MediaPipe TeamandCopybara-Service 0fc6118680 Internal change.
PiperOrigin-RevId: 526892368
2023-04-25 01:30:43 -07:00
MediaPipe TeamandCopybara-Service 56df724c36 Add customizable face stylizer module in MediaPipe model maker
PiperOrigin-RevId: 526883862
2023-04-25 00:47:45 -07:00
Prianka Liz Kariat 3390325250 Updated documentation 2023-04-25 11:23:38 +05:30
Prianka Liz Kariat 6ac39c9b93 Updated name of common objects pod 2023-04-25 04:26:13 +05:30
Prianka Liz Kariat d63d3f61d7 Added podspec for CommonObjects and Vision tasks 2023-04-25 04:22:40 +05:30
Prianka Liz Kariat 8b44a7f181 Updated text podspec 2023-04-25 04:22:18 +05:30
Prianka Liz Kariat 472947818e Updated ios cocoapods build script 2023-04-25 04:22:03 +05:30
Prianka Liz Kariat 6eee726025 Updated build rules for iOS frameworks to duplicate symbols 2023-04-25 04:21:41 +05:30
Jiuqiang TangandCopybara-Service a0eb1b696c Internal changes.
PiperOrigin-RevId: 526759809
2023-04-24 14:45:35 -07:00
MediaPipe TeamandCopybara-Service 33c8c68bba Add a default_applicable_licenses to model_maker/python/vision/core.
PiperOrigin-RevId: 526716940
2023-04-24 12:08:34 -07:00
kinaryml ca5fca1db7 Mark index as unused 2023-04-24 11:26:36 -07:00
kinaryml b511822815 Removed an unnecessary check and updated tests to check if the masks are generated or not 2023-04-24 11:23:27 -07:00
MediaPipe TeamandCopybara-Service ceb911ae06 Add nullable annotation to AudioDataProducer#setAudioConsumer
PiperOrigin-RevId: 526697945
2023-04-24 11:10:07 -07:00
Sebastian SchmidtandCopybara-Service 61854dc6a3 Create Pose Detector Web API
PiperOrigin-RevId: 526672533
2023-04-24 09:53:05 -07:00
Jiuqiang TangandCopybara-Service 6773188e26 Make FaceLandmarksConnections to be a public class.
PiperOrigin-RevId: 526667505
2023-04-24 09:34:14 -07:00
Sebastian SchmidtandCopybara-Service 35cf8c35f2 Internal change
PiperOrigin-RevId: 526658482
2023-04-24 09:01:55 -07:00
MediaPipe TeamandCopybara-Service abded49e5b Internal change
PiperOrigin-RevId: 526300079
2023-04-22 10:52:14 -07:00
MediaPipe TeamandCopybara-Service a6c1bb6324 Internal change
PiperOrigin-RevId: 526235882
2023-04-22 00:28:52 -07:00
MediaPipe TeamandCopybara-Service 58dcbc9833 Internal change
PiperOrigin-RevId: 526117263
2023-04-21 13:12:47 -07:00
kinaryml 0b1eb39870 Updated copyright 2023-04-21 11:48:06 -07:00
kinaryml 2a2a55d1b8 Added Language Detector Python API and fixed a typo in Interactive Segmenter Options' docstring 2023-04-21 11:46:21 -07:00
MediaPipe TeamandCopybara-Service a6c35e9ba5 Fixes the typos in tasks internal files.
PiperOrigin-RevId: 526063515
2023-04-21 09:46:39 -07:00
Sebastian SchmidtandCopybara-Service 9be748db00 Create MPImage type for Web
PiperOrigin-RevId: 525873209
2023-04-20 16:01:04 -07:00
Sebastian SchmidtandCopybara-Service e9bb849503 Fix Typo
PiperOrigin-RevId: 525861968
2023-04-20 15:15:13 -07:00
MediaPipe TeamandCopybara-Service bd73617e5c Internal change
PiperOrigin-RevId: 525854969
2023-04-20 14:47:17 -07:00
MediaPipe TeamandCopybara-Service 02bdb9aba0 Internal change
PiperOrigin-RevId: 525845988
2023-04-20 14:14:58 -07:00
MediaPipe TeamandCopybara-Service 983932b6dd This will fix the multiple typos in the new tasks internal files
PiperOrigin-RevId: 525788850
2023-04-20 10:43:35 -07:00
MediaPipe TeamandCopybara-Service d4c7ad0411 Internal change
PiperOrigin-RevId: 525775875
2023-04-20 10:00:01 -07:00
MediaPipe TeamandCopybara-Service a89ec882b0 Internal change
PiperOrigin-RevId: 525774601
2023-04-20 09:55:35 -07:00
Kinar RandGitHub 9032bce577 Update copyright 2023-04-20 13:21:56 +05:30
Kinar RandGitHub 21ddba0d60 Update copyright 2023-04-20 13:21:31 +05:30
MediaPipe TeamandCopybara-Service 331692577e Internal change
PiperOrigin-RevId: 525660743
2023-04-19 23:47:59 -07:00
Copybara-Service 44aa607e06 Merge pull request #4302 from kinaryml:segmenter-python-add-labels
PiperOrigin-RevId: 525571089
2023-04-19 15:46:20 -07:00
Sebastian SchmidtandCopybara-Service ffbd799b8d Extract shared types to create and test landmarks
PiperOrigin-RevId: 525568412
2023-04-19 15:37:42 -07:00
MediaPipe TeamandCopybara-Service 476c7efc18 Remove uses of ATOMIC_VAR_INIT
ATOMIC_VAR_INIT has a trivial definition
`#define ATOMIC_VAR_INIT(value) (value)`,
is deprecated in C17/C++20, and will be removed in newer standards in
newer GCC/Clang (e.g. https://reviews.llvm.org/D144196).

PiperOrigin-RevId: 525534393
2023-04-19 13:26:47 -07:00
MediaPipe TeamandCopybara-Service 5bd3282515 Internal change
PiperOrigin-RevId: 525513792
2023-04-19 12:05:44 -07:00
MediaPipe TeamandCopybara-Service 3231591f7f draw right eye with blue color
PiperOrigin-RevId: 525508840
2023-04-19 11:47:38 -07:00
MediaPipe TeamandCopybara-Service b2586e7e3b Internal change
PiperOrigin-RevId: 525495248
2023-04-19 11:01:13 -07:00
MediaPipe TeamandCopybara-Service eb62479190 Internal change
PiperOrigin-RevId: 525487344
2023-04-19 10:35:49 -07:00
Bekzhan BekbolatulyandCopybara-Service 9818ebb630 Internal change
PiperOrigin-RevId: 525476655
2023-04-19 09:58:22 -07:00
MediaPipe TeamandCopybara-Service 0aea6d90a8 Internal change
PiperOrigin-RevId: 525407296
2023-04-19 04:10:02 -07:00
MediaPipe TeamandCopybara-Service 01f4439d83 Internal change
PiperOrigin-RevId: 525399975
2023-04-19 03:33:01 -07:00
MediaPipe TeamandCopybara-Service de84696be6 Internal change
PiperOrigin-RevId: 525390694
2023-04-19 02:39:54 -07:00
MediaPipe TeamandCopybara-Service b83fa5b67d Internal change
PiperOrigin-RevId: 525365673
2023-04-19 00:17:50 -07:00
MediaPipe TeamandCopybara-Service 8c8ba9511a Internal change
PiperOrigin-RevId: 525358261
2023-04-18 23:33:46 -07:00
kinaryml f87ffd92a0 Removed optional for defaults in some tasks and updated various tests to be consistent with that of Pose Landmarker's 2023-04-18 23:28:10 -07:00
kinaryml 00f966655b Fixed a typo in a docstring 2023-04-18 22:48:37 -07:00
kinaryml 1688d0fa79 Added more pose landmarker tests and updated face landmarker tests to cover all the results 2023-04-18 22:45:46 -07:00
Kinar RandGitHub 39742b6641 Merge branch 'google:master' into pose-landmarker-python 2023-04-19 10:21:23 +05:30
kinaryml a1aab66c8d Fixed a typo in docstring 2023-04-18 21:50:27 -07:00
kinaryml 67b72e4fe9 Code cleanup 2023-04-18 21:43:38 -07:00
kinaryml 1cb404bea1 Changed labels to be a property 2023-04-18 21:31:14 -07:00
Kinar RandGitHub d621df8046 Merge branch 'google:master' into segmenter-python-add-labels 2023-04-19 09:51:42 +05:30
Sebastian SchmidtandCopybara-Service d7039c90dc Update WASM for Alpha 11
PiperOrigin-RevId: 525245471
2023-04-18 14:07:07 -07:00
Prianka Liz Kariat 99420d35f3 Update build_ios_framework.sh 2023-04-19 00:25:10 +05:30
Copybara-Service e15d98298f Merge pull request #4280 from kinaryml:image-segmenter-python-api-updates
PiperOrigin-RevId: 525204893
2023-04-18 11:36:09 -07:00
Prianka Liz Kariat f75eb57956 Update build_ios_framework.sh 2023-04-18 23:46:05 +05:30
Prianka Liz Kariat 0c4d405479 Updated bazelrc with required config 2023-04-18 23:21:14 +05:30
Prianka Liz Kariat eb0aa5056a Updated documentation 2023-04-18 23:20:11 +05:30
Prianka Liz Kariat d7c96dea6a Updated formatting of files 2023-04-18 23:10:47 +05:30
Prianka Liz Kariat 24bd7a6b9f Merge branch 'master' into ios-text-cocoapods-force-load 2023-04-18 23:03:56 +05:30
Prianka Liz Kariat 49b2c7c2cc Added iOS task text cocoapods podspec 2023-04-18 23:02:58 +05:30
Prianka Liz Kariat 7ad2b7b32f Added shell script for building cocoapods archive 2023-04-18 23:02:35 +05:30
Prianka Liz Kariat a774399630 Added targets for iOS text frameworks 2023-04-18 23:02:16 +05:30
MediaPipe TeamandCopybara-Service 64d1e74c20 Internal MediaPipe Tasks change
PiperOrigin-RevId: 525182282
2023-04-18 10:20:03 -07:00
MediaPipe TeamandCopybara-Service 3e0ed2ced0 Internal Changes
PiperOrigin-RevId: 525180095
2023-04-18 10:14:08 -07:00
kinaryml 1919b0e341 Updated docstrings for get_labels 2023-04-18 02:54:03 -07:00
kinaryml 723cb2a919 Populate labels using model metadata for the ImageSegmenter Python API 2023-04-18 02:49:13 -07:00
MediaPipe TeamandCopybara-Service 88a10de345 Internal change
PiperOrigin-RevId: 525084368
2023-04-18 02:15:02 -07:00
MediaPipe TeamandCopybara-Service b4e27c137e Internal change
PiperOrigin-RevId: 525069421
2023-04-18 00:54:16 -07:00
MediaPipe TeamandCopybara-Service 63cd09951d Internal change
PiperOrigin-RevId: 525030969
2023-04-17 21:17:08 -07:00
MediaPipe TeamandCopybara-Service 43fd744296 Internal Changes
PiperOrigin-RevId: 524997017
2023-04-17 17:43:40 -07:00
Sebastian SchmidtandCopybara-Service 47e55fcf2f Add HAND_CONNECTIONS to HandLandmarker and GestureRecognizer
PiperOrigin-RevId: 524951052
2023-04-17 14:31:40 -07:00
MediaPipe TeamandCopybara-Service 2564fec44c Internal MediaPipe Tasks change.
PiperOrigin-RevId: 524942203
2023-04-17 14:09:14 -07:00
Sebastian SchmidtandCopybara-Service b147002b7e Support new output format for InteractiveSegmenter
PiperOrigin-RevId: 524940992
2023-04-17 14:04:56 -07:00
kinaryml 5f5ce22020 Added the PoseLandmarker Python API and a simple test 2023-04-14 14:09:15 -07:00
kinaryml a745b71f97 Removed unused import 2023-04-13 21:11:20 -07:00
kinaryml a036bf70cc Removed Activation from ImageSegmenterOptions 2023-04-13 21:09:01 -07:00
kinaryml a03fa448dc Explicitly state the modes in the tests for ImageSegmenterOptions and InteractiveSegmenterOptions 2023-04-13 11:55:37 -07:00
kinaryml 3f68f90238 Deprecated output_type for the ImageSegmenter and InteractiveSegmenter APIs 2023-04-12 14:37:16 -07:00
Prianka Liz Kariat 0fcf92d7d5 Updated iOS Image Classifier to reflect new calculation for normalized rect 2023-04-11 18:18:35 +05:30
Prianka Liz Kariat 114a11dc4e Updated iOS tests to reflect the new orientation calculation. 2023-04-11 18:11:58 +05:30
Prianka Liz Kariat 27353310c3 Updated normalized rect calculation for some angles in MPPVisionTaskRunner 2023-04-11 18:11:33 +05:30
Prianka Liz Kariat 089361cd89 Split macros into helpers in Objective C Tests 2023-04-11 17:37:54 +05:30
Shivam Mishra 89491df8c1 Migrate stale management probot to Github action 2023-04-10 22:38:14 +05:30
Prianka Liz Kariat d06cf68c70 Removed detect in image with region of interest api from iOS Object Detector 2023-04-10 19:28:46 +05:30
Prianka Liz Kariat a2bab54640 Added iOS Object Detector Objective D tests 2023-04-10 19:25:37 +05:30
Prianka Liz Kariat adfe47d456 Removed roi apis from iOS object detector 2023-04-10 19:24:58 +05:30
Prianka Liz Kariat 0fd60285b5 Updated roi not allowed check in ios vision task runner 2023-04-10 19:23:32 +05:30
1384 changed files with 56558 additions and 7371 deletions
+3
View File
@@ -87,6 +87,9 @@ build:ios_fat --config=ios
build:ios_fat --ios_multi_cpus=armv7,arm64
build:ios_fat --watchos_cpus=armv7k
build:ios_sim_fat --config=ios
build:ios_sim_fat --ios_multi_cpus=x86_64,sim_arm64
build:darwin_x86_64 --apple_platform_type=macos
build:darwin_x86_64 --macos_minimum_os=10.12
build:darwin_x86_64 --cpu=darwin_x86_64
-34
View File
@@ -1,34 +0,0 @@
# Copyright 2021 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.
# ============================================================================
#
# This file was assembled from multiple pieces, whose use is documented
# throughout. Please refer to the TensorFlow dockerfiles documentation
# for more information.
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 7
# Number of days of inactivity before a stale Issue or Pull Request is closed
daysUntilClose: 7
# Only issues or pull requests with all of these labels are checked if stale. Defaults to `[]` (disabled)
onlyLabels:
- stat:awaiting response
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you.
# Comment to post when removing the stale label. Set to `false` to disable
unmarkComment: false
closeComment: >
Closing as stale. Please reopen if you'd like to work on this further.
+66
View File
@@ -0,0 +1,66 @@
# Copyright 2023 The TensorFlow 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.
# ==============================================================================
# This workflow alerts and then closes the stale issues/PRs after specific time
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/actions/stale
name: 'Close stale issues and PRs'
"on":
schedule:
- cron: "30 1 * * *"
permissions:
contents: read
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: 'actions/stale@v7'
with:
# Comma separated list of labels that can be assigned to issues to exclude them from being marked as stale.
exempt-issue-labels: 'override-stale'
# Comma separated list of labels that can be assigned to PRs to exclude them from being marked as stale.
exempt-pr-labels: "override-stale"
# Limit the No. of API calls in one run default value is 30.
operations-per-run: 500
# Prevent to remove stale label when PRs or issues are updated.
remove-stale-when-updated: false
# comment on issue if not active for more then 7 days.
stale-issue-message: 'This issue has been marked stale because it has no recent activity since 7 days. It will be closed if no further activity occurs. Thank you.'
# comment on PR if not active for more then 14 days.
stale-pr-message: 'This PR has been marked stale because it has no recent activity since 14 days. It will be closed if no further activity occurs. Thank you.'
# comment on issue if stale for more then 7 days.
close-issue-message: This issue was closed due to lack of activity after being marked stale for past 7 days.
# comment on PR if stale for more then 14 days.
close-pr-message: This PR was closed due to lack of activity after being marked stale for past 14 days.
# Number of days of inactivity before an Issue Request becomes stale
days-before-issue-stale: 7
# Number of days of inactivity before a stale Issue is closed
days-before-issue-close: 7
# reason for closed the issue default value is not_planned
close-issue-reason: completed
# Number of days of inactivity before a stale PR is closed
days-before-pr-close: 14
# Number of days of inactivity before an PR Request becomes stale
days-before-pr-stale: 14
# Check for label to stale or close the issue/PR
any-of-labels: 'stat:awaiting response'
# override stale to stalled for PR
stale-pr-label: 'stale'
# override stale to stalled for Issue
stale-issue-label: "stale"
+93 -107
View File
@@ -1,99 +1,121 @@
---
layout: default
layout: forward
target: https://developers.google.com/mediapipe
title: Home
nav_order: 1
---
![MediaPipe](https://mediapipe.dev/images/mediapipe_small.png)
----
**Attention:** *Thanks for your interest in MediaPipe! We have moved to
**Attention:** *We have moved to
[https://developers.google.com/mediapipe](https://developers.google.com/mediapipe)
as the primary developer documentation site for MediaPipe as of April 3, 2023.*
*This notice and web page will be removed on June 1, 2023.*
![MediaPipe](https://developers.google.com/static/mediapipe/images/home/hero_01_1920.png)
----
**Attention**: MediaPipe Solutions Preview is an early release. [Learn
more](https://developers.google.com/mediapipe/solutions/about#notice).
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
**On-device machine learning for everyone**
--------------------------------------------------------------------------------
Delight your customers with innovative machine learning features. MediaPipe
contains everything that you need to customize and deploy to mobile (Android,
iOS), web, desktop, edge devices, and IoT, effortlessly.
## Live ML anywhere
* [See demos](https://goo.gle/mediapipe-studio)
* [Learn more](https://developers.google.com/mediapipe/solutions)
[MediaPipe](https://google.github.io/mediapipe/) offers cross-platform, customizable
ML solutions for live and streaming media.
## Get started
![accelerated.png](https://mediapipe.dev/images/accelerated_small.png) | ![cross_platform.png](https://mediapipe.dev/images/cross_platform_small.png)
:------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------:
***End-to-End acceleration***: *Built-in fast ML inference and processing accelerated even on common hardware* | ***Build once, deploy anywhere***: *Unified solution works across Android, iOS, desktop/cloud, web and IoT*
![ready_to_use.png](https://mediapipe.dev/images/ready_to_use_small.png) | ![open_source.png](https://mediapipe.dev/images/open_source_small.png)
***Ready-to-use solutions***: *Cutting-edge ML solutions demonstrating full power of the framework* | ***Free and open source***: *Framework and solutions both under Apache 2.0, fully extensible and customizable*
You can get started with MediaPipe Solutions by by checking out any of the
developer guides for
[vision](https://developers.google.com/mediapipe/solutions/vision/object_detector),
[text](https://developers.google.com/mediapipe/solutions/text/text_classifier),
and
[audio](https://developers.google.com/mediapipe/solutions/audio/audio_classifier)
tasks. If you need help setting up a development environment for use with
MediaPipe Tasks, check out the setup guides for
[Android](https://developers.google.com/mediapipe/solutions/setup_android), [web
apps](https://developers.google.com/mediapipe/solutions/setup_web), and
[Python](https://developers.google.com/mediapipe/solutions/setup_python).
----
## Solutions
## ML solutions in MediaPipe
MediaPipe Solutions provides a suite of libraries and tools for you to quickly
apply artificial intelligence (AI) and machine learning (ML) techniques in your
applications. You can plug these solutions into your applications immediately,
customize them to your needs, and use them across multiple development
platforms. MediaPipe Solutions is part of the MediaPipe [open source
project](https://github.com/google/mediapipe), so you can further customize the
solutions code to meet your application needs.
Face Detection | Face Mesh | Iris | Hands | Pose | Holistic
:----------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: | :------:
[![face_detection](https://mediapipe.dev/images/mobile/face_detection_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/face_detection) | [![face_mesh](https://mediapipe.dev/images/mobile/face_mesh_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/face_mesh) | [![iris](https://mediapipe.dev/images/mobile/iris_tracking_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/iris) | [![hand](https://mediapipe.dev/images/mobile/hand_tracking_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/hands) | [![pose](https://mediapipe.dev/images/mobile/pose_tracking_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/pose) | [![hair_segmentation](https://mediapipe.dev/images/mobile/holistic_tracking_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/holistic)
These libraries and resources provide the core functionality for each MediaPipe
Solution:
Hair Segmentation | Object Detection | Box Tracking | Instant Motion Tracking | Objectron | KNIFT
:-------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------: | :---:
[![hair_segmentation](https://mediapipe.dev/images/mobile/hair_segmentation_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/hair_segmentation) | [![object_detection](https://mediapipe.dev/images/mobile/object_detection_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/object_detection) | [![box_tracking](https://mediapipe.dev/images/mobile/object_tracking_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/box_tracking) | [![instant_motion_tracking](https://mediapipe.dev/images/mobile/instant_motion_tracking_android_small.gif)](https://google.github.io/mediapipe/solutions/instant_motion_tracking) | [![objectron](https://mediapipe.dev/images/mobile/objectron_chair_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/objectron) | [![knift](https://mediapipe.dev/images/mobile/template_matching_android_cpu_small.gif)](https://google.github.io/mediapipe/solutions/knift)
* **MediaPipe Tasks**: Cross-platform APIs and libraries for deploying
solutions. [Learn
more](https://developers.google.com/mediapipe/solutions/tasks).
* **MediaPipe models**: Pre-trained, ready-to-run models for use with each
solution.
<!-- []() in the first cell is needed to preserve table formatting in GitHub Pages. -->
<!-- Whenever this table is updated, paste a copy to solutions/solutions.md. -->
These tools let you customize and evaluate solutions:
[]() | [Android](https://google.github.io/mediapipe/getting_started/android) | [iOS](https://google.github.io/mediapipe/getting_started/ios) | [C++](https://google.github.io/mediapipe/getting_started/cpp) | [Python](https://google.github.io/mediapipe/getting_started/python) | [JS](https://google.github.io/mediapipe/getting_started/javascript) | [Coral](https://github.com/google/mediapipe/tree/master/mediapipe/examples/coral/README.md)
:---------------------------------------------------------------------------------------- | :-------------------------------------------------------------: | :-----------------------------------------------------: | :-----------------------------------------------------: | :-----------------------------------------------------------: | :-----------------------------------------------------------: | :--------------------------------------------------------------------:
[Face Detection](https://google.github.io/mediapipe/solutions/face_detection) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
[Face Mesh](https://google.github.io/mediapipe/solutions/face_mesh) | ✅ | ✅ | ✅ | ✅ | ✅ |
[Iris](https://google.github.io/mediapipe/solutions/iris) | ✅ | ✅ | ✅ | | |
[Hands](https://google.github.io/mediapipe/solutions/hands) | ✅ | ✅ | ✅ | ✅ | ✅ |
[Pose](https://google.github.io/mediapipe/solutions/pose) | ✅ | ✅ | ✅ | ✅ | ✅ |
[Holistic](https://google.github.io/mediapipe/solutions/holistic) | ✅ | ✅ | ✅ | ✅ | ✅ |
[Selfie Segmentation](https://google.github.io/mediapipe/solutions/selfie_segmentation) | ✅ | ✅ | ✅ | ✅ | ✅ |
[Hair Segmentation](https://google.github.io/mediapipe/solutions/hair_segmentation) | ✅ | | ✅ | | |
[Object Detection](https://google.github.io/mediapipe/solutions/object_detection) | ✅ | ✅ | ✅ | | | ✅
[Box Tracking](https://google.github.io/mediapipe/solutions/box_tracking) | ✅ | ✅ | ✅ | | |
[Instant Motion Tracking](https://google.github.io/mediapipe/solutions/instant_motion_tracking) | ✅ | | | | |
[Objectron](https://google.github.io/mediapipe/solutions/objectron) | ✅ | | ✅ | ✅ | ✅ |
[KNIFT](https://google.github.io/mediapipe/solutions/knift) | ✅ | | | | |
[AutoFlip](https://google.github.io/mediapipe/solutions/autoflip) | | | ✅ | | |
[MediaSequence](https://google.github.io/mediapipe/solutions/media_sequence) | | | ✅ | | |
[YouTube 8M](https://google.github.io/mediapipe/solutions/youtube_8m) | | | ✅ | | |
* **MediaPipe Model Maker**: Customize models for solutions with your data.
[Learn more](https://developers.google.com/mediapipe/solutions/model_maker).
* **MediaPipe Studio**: Visualize, evaluate, and benchmark solutions in your
browser. [Learn
more](https://developers.google.com/mediapipe/solutions/studio).
See also
[MediaPipe Models and Model Cards](https://google.github.io/mediapipe/solutions/models)
for ML models released in MediaPipe.
### Legacy solutions
## Getting started
We have ended support for [these MediaPipe Legacy Solutions](https://developers.google.com/mediapipe/solutions/guide#legacy)
as of March 1, 2023. All other MediaPipe Legacy Solutions will be upgraded to
a new MediaPipe Solution. See the [Solutions guide](https://developers.google.com/mediapipe/solutions/guide#legacy)
for details. The [code repository](https://github.com/google/mediapipe/tree/master/mediapipe)
and prebuilt binaries for all MediaPipe Legacy Solutions will continue to be
provided on an as-is basis.
To start using MediaPipe
[solutions](https://google.github.io/mediapipe/solutions/solutions) with only a few
lines code, see example code and demos in
[MediaPipe in Python](https://google.github.io/mediapipe/getting_started/python) and
[MediaPipe in JavaScript](https://google.github.io/mediapipe/getting_started/javascript).
For more on the legacy solutions, see the [documentation](https://github.com/google/mediapipe/tree/master/docs/solutions).
To use MediaPipe in C++, Android and iOS, which allow further customization of
the [solutions](https://google.github.io/mediapipe/solutions/solutions) as well as
building your own, learn how to
[install](https://google.github.io/mediapipe/getting_started/install) MediaPipe and
start building example applications in
[C++](https://google.github.io/mediapipe/getting_started/cpp),
[Android](https://google.github.io/mediapipe/getting_started/android) and
[iOS](https://google.github.io/mediapipe/getting_started/ios).
## Framework
The source code is hosted in the
[MediaPipe Github repository](https://github.com/google/mediapipe), and you can
run code search using
[Google Open Source Code Search](https://cs.opensource.google/mediapipe/mediapipe).
To start using MediaPipe Framework, [install MediaPipe
Framework](https://developers.google.com/mediapipe/framework/getting_started/install)
and start building example applications in C++, Android, and iOS.
## Publications
[MediaPipe Framework](https://developers.google.com/mediapipe/framework) is the
low-level component used to build efficient on-device machine learning
pipelines, similar to the premade MediaPipe Solutions.
Before using MediaPipe Framework, familiarize yourself with the following key
[Framework
concepts](https://developers.google.com/mediapipe/framework/framework_concepts/overview.md):
* [Packets](https://developers.google.com/mediapipe/framework/framework_concepts/packets.md)
* [Graphs](https://developers.google.com/mediapipe/framework/framework_concepts/graphs.md)
* [Calculators](https://developers.google.com/mediapipe/framework/framework_concepts/calculators.md)
## Community
* [Slack community](https://mediapipe.page.link/joinslack) for MediaPipe
users.
* [Discuss](https://groups.google.com/forum/#!forum/mediapipe) - General
community discussion around MediaPipe.
* [Awesome MediaPipe](https://mediapipe.page.link/awesome-mediapipe) - A
curated list of awesome MediaPipe related frameworks, libraries and
software.
## Contributing
We welcome contributions. Please follow these
[guidelines](https://github.com/google/mediapipe/blob/master/CONTRIBUTING.md).
We use GitHub issues for tracking requests and bugs. Please post questions to
the MediaPipe Stack Overflow with a `mediapipe` tag.
## Resources
### Publications
* [Bringing artworks to life with AR](https://developers.googleblog.com/2021/07/bringing-artworks-to-life-with-ar.html)
in Google Developers Blog
@@ -102,7 +124,8 @@ run code search using
* [SignAll SDK: Sign language interface using MediaPipe is now available for
developers](https://developers.googleblog.com/2021/04/signall-sdk-sign-language-interface-using-mediapipe-now-available.html)
in Google Developers Blog
* [MediaPipe Holistic - Simultaneous Face, Hand and Pose Prediction, on Device](https://ai.googleblog.com/2020/12/mediapipe-holistic-simultaneous-face.html)
* [MediaPipe Holistic - Simultaneous Face, Hand and Pose Prediction, on
Device](https://ai.googleblog.com/2020/12/mediapipe-holistic-simultaneous-face.html)
in Google AI Blog
* [Background Features in Google Meet, Powered by Web ML](https://ai.googleblog.com/2020/10/background-features-in-google-meet.html)
in Google AI Blog
@@ -130,43 +153,6 @@ run code search using
in Google AI Blog
* [MediaPipe: A Framework for Building Perception Pipelines](https://arxiv.org/abs/1906.08172)
## Videos
### Videos
* [YouTube Channel](https://www.youtube.com/c/MediaPipe)
## Events
* [MediaPipe Seattle Meetup, Google Building Waterside, 13 Feb 2020](https://mediapipe.page.link/seattle2020)
* [AI Nextcon 2020, 12-16 Feb 2020, Seattle](http://aisea20.xnextcon.com/)
* [MediaPipe Madrid Meetup, 16 Dec 2019](https://www.meetup.com/Madrid-AI-Developers-Group/events/266329088/)
* [MediaPipe London Meetup, Google 123 Building, 12 Dec 2019](https://www.meetup.com/London-AI-Tech-Talk/events/266329038)
* [ML Conference, Berlin, 11 Dec 2019](https://mlconference.ai/machine-learning-advanced-development/mediapipe-building-real-time-cross-platform-mobile-web-edge-desktop-video-audio-ml-pipelines/)
* [MediaPipe Berlin Meetup, Google Berlin, 11 Dec 2019](https://www.meetup.com/Berlin-AI-Tech-Talk/events/266328794/)
* [The 3rd Workshop on YouTube-8M Large Scale Video Understanding Workshop,
Seoul, Korea ICCV
2019](https://research.google.com/youtube8m/workshop2019/index.html)
* [AI DevWorld 2019, 10 Oct 2019, San Jose, CA](https://aidevworld.com)
* [Google Industry Workshop at ICIP 2019, 24 Sept 2019, Taipei, Taiwan](http://2019.ieeeicip.org/?action=page4&id=14#Google)
([presentation](https://docs.google.com/presentation/d/e/2PACX-1vRIBBbO_LO9v2YmvbHHEt1cwyqH6EjDxiILjuT0foXy1E7g6uyh4CesB2DkkEwlRDO9_lWfuKMZx98T/pub?start=false&loop=false&delayms=3000&slide=id.g556cc1a659_0_5))
* [Open sourced at CVPR 2019, 17~20 June, Long Beach, CA](https://sites.google.com/corp/view/perception-cv4arvr/mediapipe)
## Community
* [Awesome MediaPipe](https://mediapipe.page.link/awesome-mediapipe) - A
curated list of awesome MediaPipe related frameworks, libraries and software
* [Slack community](https://mediapipe.page.link/joinslack) for MediaPipe users
* [Discuss](https://groups.google.com/forum/#!forum/mediapipe) - General
community discussion around MediaPipe
## Alpha disclaimer
MediaPipe is currently in alpha at v0.7. We may be still making breaking API
changes and expect to get to stable APIs by v1.0.
## Contributing
We welcome contributions. Please follow these
[guidelines](https://github.com/google/mediapipe/blob/master/CONTRIBUTING.md).
We use GitHub issues for tracking requests and bugs. Please post questions to
the MediaPipe Stack Overflow with a `mediapipe` tag.
+35 -17
View File
@@ -45,12 +45,13 @@ http_archive(
)
http_archive(
name = "rules_foreign_cc",
strip_prefix = "rules_foreign_cc-0.1.0",
url = "https://github.com/bazelbuild/rules_foreign_cc/archive/0.1.0.zip",
name = "rules_foreign_cc",
sha256 = "2a4d07cd64b0719b39a7c12218a3e507672b82a97b98c6a89d38565894cf7c51",
strip_prefix = "rules_foreign_cc-0.9.0",
url = "https://github.com/bazelbuild/rules_foreign_cc/archive/refs/tags/0.9.0.tar.gz",
)
load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependencies")
load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
rules_foreign_cc_dependencies()
@@ -156,22 +157,22 @@ http_archive(
# 2020-08-21
http_archive(
name = "com_github_glog_glog",
strip_prefix = "glog-0a2e5931bd5ff22fd3bf8999eb8ce776f159cda6",
sha256 = "58c9b3b6aaa4dd8b836c0fd8f65d0f941441fb95e27212c5eeb9979cfd3592ab",
strip_prefix = "glog-3a0d4d22c5ae0b9a2216988411cfa6bf860cc372",
sha256 = "170d08f80210b82d95563f4723a15095eff1aad1863000e8eeb569c96a98fefb",
urls = [
"https://github.com/google/glog/archive/0a2e5931bd5ff22fd3bf8999eb8ce776f159cda6.zip",
"https://github.com/google/glog/archive/3a0d4d22c5ae0b9a2216988411cfa6bf860cc372.zip",
],
)
http_archive(
name = "com_github_glog_glog_no_gflags",
strip_prefix = "glog-0a2e5931bd5ff22fd3bf8999eb8ce776f159cda6",
sha256 = "58c9b3b6aaa4dd8b836c0fd8f65d0f941441fb95e27212c5eeb9979cfd3592ab",
strip_prefix = "glog-3a0d4d22c5ae0b9a2216988411cfa6bf860cc372",
sha256 = "170d08f80210b82d95563f4723a15095eff1aad1863000e8eeb569c96a98fefb",
build_file = "@//third_party:glog_no_gflags.BUILD",
urls = [
"https://github.com/google/glog/archive/0a2e5931bd5ff22fd3bf8999eb8ce776f159cda6.zip",
"https://github.com/google/glog/archive/3a0d4d22c5ae0b9a2216988411cfa6bf860cc372.zip",
],
patches = [
"@//third_party:com_github_glog_glog_9779e5ea6ef59562b030248947f787d1256132ae.diff",
"@//third_party:com_github_glog_glog.diff",
],
patch_args = [
"-p1",
@@ -266,10 +267,10 @@ http_archive(
http_archive(
name = "com_googlesource_code_re2",
sha256 = "e06b718c129f4019d6e7aa8b7631bee38d3d450dd980246bfaf493eb7db67868",
strip_prefix = "re2-fe4a310131c37f9a7e7f7816fa6ce2a8b27d65a8",
sha256 = "ef516fb84824a597c4d5d0d6d330daedb18363b5a99eda87d027e6bdd9cba299",
strip_prefix = "re2-03da4fc0857c285e3a26782f6bc8931c4c950df4",
urls = [
"https://github.com/google/re2/archive/fe4a310131c37f9a7e7f7816fa6ce2a8b27d65a8.tar.gz",
"https://github.com/google/re2/archive/03da4fc0857c285e3a26782f6bc8931c4c950df4.tar.gz",
],
)
@@ -375,6 +376,22 @@ http_archive(
url = "https://github.com/opencv/opencv/releases/download/3.2.0/opencv-3.2.0-ios-framework.zip",
)
# Building an opencv.xcframework from the OpenCV 4.5.3 sources is necessary for
# MediaPipe iOS Task Libraries to be supported on arm64(M1) Macs. An
# `opencv.xcframework` archive has not been released and it is recommended to
# build the same from source using a script provided in OpenCV 4.5.0 upwards.
# OpenCV is fixed to version to 4.5.3 since swift support can only be disabled
# from 4.5.3 upwards. This is needed to avoid errors when the library is linked
# in Xcode. Swift support will be added in when the final binary MediaPipe iOS
# Task libraries are built.
http_archive(
name = "ios_opencv_source",
sha256 = "a61e7a4618d353140c857f25843f39b2abe5f451b018aab1604ef0bc34cd23d5",
build_file = "@//third_party:opencv_ios_source.BUILD",
type = "zip",
url = "https://github.com/opencv/opencv/archive/refs/tags/4.5.3.zip",
)
http_archive(
name = "stblib",
strip_prefix = "stb-b42009b3b9d4ca35bc703f5310eedc74f584be58",
@@ -468,9 +485,10 @@ http_archive(
)
# TensorFlow repo should always go after the other external dependencies.
# TF on 2023-04-12.
_TENSORFLOW_GIT_COMMIT = "d712c0c9e24519cc8cd3720279666720d1000eee"
_TENSORFLOW_SHA256 = "ba98de6ea5f720071246691a1536ecd5e1b1763033e8c82a1e721a06d3dfd4c1"
# TF on 2023-06-13.
_TENSORFLOW_GIT_COMMIT = "491681a5620e41bf079a582ac39c585cc86878b9"
# curl -L https://github.com/tensorflow/tensorflow/archive/<TENSORFLOW_GIT_COMMIT>.tar.gz | shasum -a 256
_TENSORFLOW_SHA256 = "9f76389af7a2835e68413322c1eaabfadc912f02a76d71dc16be507f9ca3d3ac"
http_archive(
name = "org_tensorflow",
urls = [
+13 -2
View File
@@ -1,4 +1,4 @@
# Copyright 2022 The MediaPipe Authors. All Rights Reserved.
# Copyright 2022 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
# ==============================================================================
"""Generate Java reference docs for MediaPipe."""
import pathlib
import shutil
from absl import app
from absl import flags
@@ -41,7 +42,9 @@ def main(_) -> None:
mp_root = pathlib.Path(__file__)
while (mp_root := mp_root.parent).name != 'mediapipe':
# Find the nearest `mediapipe` dir.
pass
if not mp_root.name:
# We've hit the filesystem root - abort.
raise FileNotFoundError('"mediapipe" root not found')
# Find the root from which all packages are relative.
root = mp_root.parent
@@ -51,6 +54,14 @@ def main(_) -> None:
if (mp_root / 'mediapipe').exists():
mp_root = mp_root / 'mediapipe'
# We need to copy this into the tasks dir to ensure we don't leave broken
# links in the generated docs.
old_api_dir = 'java/com/google/mediapipe/framework/image'
shutil.copytree(
mp_root / old_api_dir,
mp_root / 'tasks' / old_api_dir,
dirs_exist_ok=True)
gen_java.gen_java_docs(
package='com.google.mediapipe',
source_path=mp_root / 'tasks/java',
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright 2022 The MediaPipe Authors. All Rights Reserved.
# Copyright 2022 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.
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright 2022 The MediaPipe Authors. All Rights Reserved.
# Copyright 2022 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.
+93 -107
View File
@@ -1,99 +1,121 @@
---
layout: default
layout: forward
target: https://developers.google.com/mediapipe
title: Home
nav_order: 1
---
![MediaPipe](https://mediapipe.dev/images/mediapipe_small.png)
----
**Attention:** *Thanks for your interest in MediaPipe! We have moved to
**Attention:** *We have moved to
[https://developers.google.com/mediapipe](https://developers.google.com/mediapipe)
as the primary developer documentation site for MediaPipe as of April 3, 2023.*
*This notice and web page will be removed on June 1, 2023.*
![MediaPipe](https://developers.google.com/static/mediapipe/images/home/hero_01_1920.png)
----
**Attention**: MediaPipe Solutions Preview is an early release. [Learn
more](https://developers.google.com/mediapipe/solutions/about#notice).
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
**On-device machine learning for everyone**
--------------------------------------------------------------------------------
Delight your customers with innovative machine learning features. MediaPipe
contains everything that you need to customize and deploy to mobile (Android,
iOS), web, desktop, edge devices, and IoT, effortlessly.
## Live ML anywhere
* [See demos](https://goo.gle/mediapipe-studio)
* [Learn more](https://developers.google.com/mediapipe/solutions)
[MediaPipe](https://google.github.io/mediapipe/) offers cross-platform, customizable
ML solutions for live and streaming media.
## Get started
![accelerated.png](https://mediapipe.dev/images/accelerated_small.png) | ![cross_platform.png](https://mediapipe.dev/images/cross_platform_small.png)
:------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------:
***End-to-End acceleration***: *Built-in fast ML inference and processing accelerated even on common hardware* | ***Build once, deploy anywhere***: *Unified solution works across Android, iOS, desktop/cloud, web and IoT*
![ready_to_use.png](https://mediapipe.dev/images/ready_to_use_small.png) | ![open_source.png](https://mediapipe.dev/images/open_source_small.png)
***Ready-to-use solutions***: *Cutting-edge ML solutions demonstrating full power of the framework* | ***Free and open source***: *Framework and solutions both under Apache 2.0, fully extensible and customizable*
You can get started with MediaPipe Solutions by by checking out any of the
developer guides for
[vision](https://developers.google.com/mediapipe/solutions/vision/object_detector),
[text](https://developers.google.com/mediapipe/solutions/text/text_classifier),
and
[audio](https://developers.google.com/mediapipe/solutions/audio/audio_classifier)
tasks. If you need help setting up a development environment for use with
MediaPipe Tasks, check out the setup guides for
[Android](https://developers.google.com/mediapipe/solutions/setup_android), [web
apps](https://developers.google.com/mediapipe/solutions/setup_web), and
[Python](https://developers.google.com/mediapipe/solutions/setup_python).
----
## Solutions
## ML solutions in MediaPipe
MediaPipe Solutions provides a suite of libraries and tools for you to quickly
apply artificial intelligence (AI) and machine learning (ML) techniques in your
applications. You can plug these solutions into your applications immediately,
customize them to your needs, and use them across multiple development
platforms. MediaPipe Solutions is part of the MediaPipe [open source
project](https://github.com/google/mediapipe), so you can further customize the
solutions code to meet your application needs.
Face Detection | Face Mesh | Iris | Hands | Pose | Holistic
:----------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: | :------:
[![face_detection](https://mediapipe.dev/images/mobile/face_detection_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/face_detection) | [![face_mesh](https://mediapipe.dev/images/mobile/face_mesh_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/face_mesh) | [![iris](https://mediapipe.dev/images/mobile/iris_tracking_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/iris) | [![hand](https://mediapipe.dev/images/mobile/hand_tracking_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/hands) | [![pose](https://mediapipe.dev/images/mobile/pose_tracking_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/pose) | [![hair_segmentation](https://mediapipe.dev/images/mobile/holistic_tracking_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/holistic)
These libraries and resources provide the core functionality for each MediaPipe
Solution:
Hair Segmentation | Object Detection | Box Tracking | Instant Motion Tracking | Objectron | KNIFT
:-------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------: | :---:
[![hair_segmentation](https://mediapipe.dev/images/mobile/hair_segmentation_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/hair_segmentation) | [![object_detection](https://mediapipe.dev/images/mobile/object_detection_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/object_detection) | [![box_tracking](https://mediapipe.dev/images/mobile/object_tracking_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/box_tracking) | [![instant_motion_tracking](https://mediapipe.dev/images/mobile/instant_motion_tracking_android_small.gif)](https://google.github.io/mediapipe/solutions/instant_motion_tracking) | [![objectron](https://mediapipe.dev/images/mobile/objectron_chair_android_gpu_small.gif)](https://google.github.io/mediapipe/solutions/objectron) | [![knift](https://mediapipe.dev/images/mobile/template_matching_android_cpu_small.gif)](https://google.github.io/mediapipe/solutions/knift)
* **MediaPipe Tasks**: Cross-platform APIs and libraries for deploying
solutions. [Learn
more](https://developers.google.com/mediapipe/solutions/tasks).
* **MediaPipe models**: Pre-trained, ready-to-run models for use with each
solution.
<!-- []() in the first cell is needed to preserve table formatting in GitHub Pages. -->
<!-- Whenever this table is updated, paste a copy to solutions/solutions.md. -->
These tools let you customize and evaluate solutions:
[]() | [Android](https://google.github.io/mediapipe/getting_started/android) | [iOS](https://google.github.io/mediapipe/getting_started/ios) | [C++](https://google.github.io/mediapipe/getting_started/cpp) | [Python](https://google.github.io/mediapipe/getting_started/python) | [JS](https://google.github.io/mediapipe/getting_started/javascript) | [Coral](https://github.com/google/mediapipe/tree/master/mediapipe/examples/coral/README.md)
:---------------------------------------------------------------------------------------- | :-------------------------------------------------------------: | :-----------------------------------------------------: | :-----------------------------------------------------: | :-----------------------------------------------------------: | :-----------------------------------------------------------: | :--------------------------------------------------------------------:
[Face Detection](https://google.github.io/mediapipe/solutions/face_detection) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
[Face Mesh](https://google.github.io/mediapipe/solutions/face_mesh) | ✅ | ✅ | ✅ | ✅ | ✅ |
[Iris](https://google.github.io/mediapipe/solutions/iris) | ✅ | ✅ | ✅ | | |
[Hands](https://google.github.io/mediapipe/solutions/hands) | ✅ | ✅ | ✅ | ✅ | ✅ |
[Pose](https://google.github.io/mediapipe/solutions/pose) | ✅ | ✅ | ✅ | ✅ | ✅ |
[Holistic](https://google.github.io/mediapipe/solutions/holistic) | ✅ | ✅ | ✅ | ✅ | ✅ |
[Selfie Segmentation](https://google.github.io/mediapipe/solutions/selfie_segmentation) | ✅ | ✅ | ✅ | ✅ | ✅ |
[Hair Segmentation](https://google.github.io/mediapipe/solutions/hair_segmentation) | ✅ | | ✅ | | |
[Object Detection](https://google.github.io/mediapipe/solutions/object_detection) | ✅ | ✅ | ✅ | | | ✅
[Box Tracking](https://google.github.io/mediapipe/solutions/box_tracking) | ✅ | ✅ | ✅ | | |
[Instant Motion Tracking](https://google.github.io/mediapipe/solutions/instant_motion_tracking) | ✅ | | | | |
[Objectron](https://google.github.io/mediapipe/solutions/objectron) | ✅ | | ✅ | ✅ | ✅ |
[KNIFT](https://google.github.io/mediapipe/solutions/knift) | ✅ | | | | |
[AutoFlip](https://google.github.io/mediapipe/solutions/autoflip) | | | ✅ | | |
[MediaSequence](https://google.github.io/mediapipe/solutions/media_sequence) | | | ✅ | | |
[YouTube 8M](https://google.github.io/mediapipe/solutions/youtube_8m) | | | ✅ | | |
* **MediaPipe Model Maker**: Customize models for solutions with your data.
[Learn more](https://developers.google.com/mediapipe/solutions/model_maker).
* **MediaPipe Studio**: Visualize, evaluate, and benchmark solutions in your
browser. [Learn
more](https://developers.google.com/mediapipe/solutions/studio).
See also
[MediaPipe Models and Model Cards](https://google.github.io/mediapipe/solutions/models)
for ML models released in MediaPipe.
### Legacy solutions
## Getting started
We have ended support for [these MediaPipe Legacy Solutions](https://developers.google.com/mediapipe/solutions/guide#legacy)
as of March 1, 2023. All other MediaPipe Legacy Solutions will be upgraded to
a new MediaPipe Solution. See the [Solutions guide](https://developers.google.com/mediapipe/solutions/guide#legacy)
for details. The [code repository](https://github.com/google/mediapipe/tree/master/mediapipe)
and prebuilt binaries for all MediaPipe Legacy Solutions will continue to be
provided on an as-is basis.
To start using MediaPipe
[solutions](https://google.github.io/mediapipe/solutions/solutions) with only a few
lines code, see example code and demos in
[MediaPipe in Python](https://google.github.io/mediapipe/getting_started/python) and
[MediaPipe in JavaScript](https://google.github.io/mediapipe/getting_started/javascript).
For more on the legacy solutions, see the [documentation](https://github.com/google/mediapipe/tree/master/docs/solutions).
To use MediaPipe in C++, Android and iOS, which allow further customization of
the [solutions](https://google.github.io/mediapipe/solutions/solutions) as well as
building your own, learn how to
[install](https://google.github.io/mediapipe/getting_started/install) MediaPipe and
start building example applications in
[C++](https://google.github.io/mediapipe/getting_started/cpp),
[Android](https://google.github.io/mediapipe/getting_started/android) and
[iOS](https://google.github.io/mediapipe/getting_started/ios).
## Framework
The source code is hosted in the
[MediaPipe Github repository](https://github.com/google/mediapipe), and you can
run code search using
[Google Open Source Code Search](https://cs.opensource.google/mediapipe/mediapipe).
To start using MediaPipe Framework, [install MediaPipe
Framework](https://developers.google.com/mediapipe/framework/getting_started/install)
and start building example applications in C++, Android, and iOS.
## Publications
[MediaPipe Framework](https://developers.google.com/mediapipe/framework) is the
low-level component used to build efficient on-device machine learning
pipelines, similar to the premade MediaPipe Solutions.
Before using MediaPipe Framework, familiarize yourself with the following key
[Framework
concepts](https://developers.google.com/mediapipe/framework/framework_concepts/overview.md):
* [Packets](https://developers.google.com/mediapipe/framework/framework_concepts/packets.md)
* [Graphs](https://developers.google.com/mediapipe/framework/framework_concepts/graphs.md)
* [Calculators](https://developers.google.com/mediapipe/framework/framework_concepts/calculators.md)
## Community
* [Slack community](https://mediapipe.page.link/joinslack) for MediaPipe
users.
* [Discuss](https://groups.google.com/forum/#!forum/mediapipe) - General
community discussion around MediaPipe.
* [Awesome MediaPipe](https://mediapipe.page.link/awesome-mediapipe) - A
curated list of awesome MediaPipe related frameworks, libraries and
software.
## Contributing
We welcome contributions. Please follow these
[guidelines](https://github.com/google/mediapipe/blob/master/CONTRIBUTING.md).
We use GitHub issues for tracking requests and bugs. Please post questions to
the MediaPipe Stack Overflow with a `mediapipe` tag.
## Resources
### Publications
* [Bringing artworks to life with AR](https://developers.googleblog.com/2021/07/bringing-artworks-to-life-with-ar.html)
in Google Developers Blog
@@ -102,7 +124,8 @@ run code search using
* [SignAll SDK: Sign language interface using MediaPipe is now available for
developers](https://developers.googleblog.com/2021/04/signall-sdk-sign-language-interface-using-mediapipe-now-available.html)
in Google Developers Blog
* [MediaPipe Holistic - Simultaneous Face, Hand and Pose Prediction, on Device](https://ai.googleblog.com/2020/12/mediapipe-holistic-simultaneous-face.html)
* [MediaPipe Holistic - Simultaneous Face, Hand and Pose Prediction, on
Device](https://ai.googleblog.com/2020/12/mediapipe-holistic-simultaneous-face.html)
in Google AI Blog
* [Background Features in Google Meet, Powered by Web ML](https://ai.googleblog.com/2020/10/background-features-in-google-meet.html)
in Google AI Blog
@@ -130,43 +153,6 @@ run code search using
in Google AI Blog
* [MediaPipe: A Framework for Building Perception Pipelines](https://arxiv.org/abs/1906.08172)
## Videos
### Videos
* [YouTube Channel](https://www.youtube.com/c/MediaPipe)
## Events
* [MediaPipe Seattle Meetup, Google Building Waterside, 13 Feb 2020](https://mediapipe.page.link/seattle2020)
* [AI Nextcon 2020, 12-16 Feb 2020, Seattle](http://aisea20.xnextcon.com/)
* [MediaPipe Madrid Meetup, 16 Dec 2019](https://www.meetup.com/Madrid-AI-Developers-Group/events/266329088/)
* [MediaPipe London Meetup, Google 123 Building, 12 Dec 2019](https://www.meetup.com/London-AI-Tech-Talk/events/266329038)
* [ML Conference, Berlin, 11 Dec 2019](https://mlconference.ai/machine-learning-advanced-development/mediapipe-building-real-time-cross-platform-mobile-web-edge-desktop-video-audio-ml-pipelines/)
* [MediaPipe Berlin Meetup, Google Berlin, 11 Dec 2019](https://www.meetup.com/Berlin-AI-Tech-Talk/events/266328794/)
* [The 3rd Workshop on YouTube-8M Large Scale Video Understanding Workshop,
Seoul, Korea ICCV
2019](https://research.google.com/youtube8m/workshop2019/index.html)
* [AI DevWorld 2019, 10 Oct 2019, San Jose, CA](https://aidevworld.com)
* [Google Industry Workshop at ICIP 2019, 24 Sept 2019, Taipei, Taiwan](http://2019.ieeeicip.org/?action=page4&id=14#Google)
([presentation](https://docs.google.com/presentation/d/e/2PACX-1vRIBBbO_LO9v2YmvbHHEt1cwyqH6EjDxiILjuT0foXy1E7g6uyh4CesB2DkkEwlRDO9_lWfuKMZx98T/pub?start=false&loop=false&delayms=3000&slide=id.g556cc1a659_0_5))
* [Open sourced at CVPR 2019, 17~20 June, Long Beach, CA](https://sites.google.com/corp/view/perception-cv4arvr/mediapipe)
## Community
* [Awesome MediaPipe](https://mediapipe.page.link/awesome-mediapipe) - A
curated list of awesome MediaPipe related frameworks, libraries and software
* [Slack community](https://mediapipe.page.link/joinslack) for MediaPipe users
* [Discuss](https://groups.google.com/forum/#!forum/mediapipe) - General
community discussion around MediaPipe
## Alpha disclaimer
MediaPipe is currently in alpha at v0.7. We may be still making breaking API
changes and expect to get to stable APIs by v1.0.
## Contributing
We welcome contributions. Please follow these
[guidelines](https://github.com/google/mediapipe/blob/master/CONTRIBUTING.md).
We use GitHub issues for tracking requests and bugs. Please post questions to
the MediaPipe Stack Overflow with a `mediapipe` tag.
+2 -2
View File
@@ -20,9 +20,9 @@ nav_order: 1
---
**Attention:** *Thank you for your interest in MediaPipe Solutions.
As of March 1, 2023, this solution is planned to be upgraded to a new MediaPipe
As of May 10, 2023, this solution was upgraded to a new MediaPipe
Solution. For more information, see the
[MediaPipe Solutions](https://developers.google.com/mediapipe/solutions/guide#legacy)
[MediaPipe Solutions](https://developers.google.com/mediapipe/solutions/vision/face_detector)
site.*
----
+2 -2
View File
@@ -20,9 +20,9 @@ nav_order: 2
---
**Attention:** *Thank you for your interest in MediaPipe Solutions.
As of March 1, 2023, this solution is planned to be upgraded to a new MediaPipe
As of May 10, 2023, this solution was upgraded to a new MediaPipe
Solution. For more information, see the
[MediaPipe Solutions](https://developers.google.com/mediapipe/solutions/guide#legacy)
[MediaPipe Solutions](https://developers.google.com/mediapipe/solutions/vision/face_landmarker)
site.*
----
+2 -2
View File
@@ -20,9 +20,9 @@ nav_order: 3
---
**Attention:** *Thank you for your interest in MediaPipe Solutions.
As of March 1, 2023, this solution is planned to be upgraded to a new MediaPipe
As of May 10, 2023, this solution was upgraded to a new MediaPipe
Solution. For more information, see the
[MediaPipe Solutions](https://developers.google.com/mediapipe/solutions/guide#legacy)
[MediaPipe Solutions](https://developers.google.com/mediapipe/solutions/vision/face_landmarker)
site.*
----
+2 -2
View File
@@ -22,9 +22,9 @@ nav_order: 5
---
**Attention:** *Thank you for your interest in MediaPipe Solutions.
As of March 1, 2023, this solution is planned to be upgraded to a new MediaPipe
As of May 10, 2023, this solution was upgraded to a new MediaPipe
Solution. For more information, see the
[MediaPipe Solutions](https://developers.google.com/mediapipe/solutions/vision/pose_landmarker/)
[MediaPipe Solutions](https://developers.google.com/mediapipe/solutions/vision/pose_landmarker)
site.*
----
+1 -1
View File
@@ -21,7 +21,7 @@ nav_order: 1
---
**Attention:** *Thank you for your interest in MediaPipe Solutions.
As of March 1, 2023, this solution is planned to be upgraded to a new MediaPipe
As of May 10, 2023, this solution was upgraded to a new MediaPipe
Solution. For more information, see the
[MediaPipe Solutions](https://developers.google.com/mediapipe/solutions/vision/pose_landmarker/)
site.*
+3 -11
View File
@@ -1,5 +1,6 @@
---
layout: default
layout: forward
target: https://developers.google.com/mediapipe/solutions/guide#legacy
title: MediaPipe Legacy Solutions
nav_order: 3
has_children: true
@@ -13,8 +14,7 @@ has_toc: false
{:toc}
---
**Attention:** *Thank you for your interest in MediaPipe Solutions. We have
ended support for
**Attention:** *We have ended support for
[these MediaPipe Legacy Solutions](https://developers.google.com/mediapipe/solutions/guide#legacy)
as of March 1, 2023. All other
[MediaPipe Legacy Solutions will be upgraded](https://developers.google.com/mediapipe/solutions/guide#legacy)
@@ -25,14 +25,6 @@ be provided on an as-is basis. We encourage you to check out the new MediaPipe
Solutions at:
[https://developers.google.com/mediapipe/solutions](https://developers.google.com/mediapipe/solutions)*
*This notice and web page will be removed on June 1, 2023.*
----
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
----
MediaPipe offers open source cross-platform, customizable ML solutions for live
+93 -57
View File
@@ -68,30 +68,108 @@ config_setting(
visibility = ["//visibility:public"],
)
# Note: this cannot just match "apple_platform_type": "macos" because that option
# defaults to "macos" even when building on Linux!
alias(
# Generic MacOS.
config_setting(
name = "macos",
actual = select({
":macos_i386": ":macos_i386",
":macos_x86_64": ":macos_x86_64",
":macos_arm64": ":macos_arm64",
"//conditions:default": ":macos_i386", # Arbitrarily chosen from above.
}),
constraint_values = [
"@platforms//os:macos",
],
visibility = ["//visibility:public"],
)
# Note: this also matches on crosstool_top so that it does not produce ambiguous
# selectors when used together with "android".
# MacOS x86 64-bit.
config_setting(
name = "macos_x86_64",
constraint_values = [
"@platforms//os:macos",
"@platforms//cpu:x86_64",
],
visibility = ["//visibility:public"],
)
# MacOS ARM64.
config_setting(
name = "macos_arm64",
constraint_values = [
"@platforms//os:macos",
"@platforms//cpu:arm64",
],
visibility = ["//visibility:public"],
)
# Generic iOS.
config_setting(
name = "ios",
values = {
"crosstool_top": "@bazel_tools//tools/cpp:toolchain",
"apple_platform_type": "ios",
},
constraint_values = [
"@platforms//os:ios",
],
visibility = ["//visibility:public"],
)
# iOS device ARM32.
config_setting(
name = "ios_armv7",
constraint_values = [
"@platforms//os:ios",
"@platforms//cpu:arm",
],
visibility = ["//visibility:public"],
)
# iOS device ARM64.
config_setting(
name = "ios_arm64",
constraint_values = [
"@platforms//os:ios",
"@platforms//cpu:arm64",
],
visibility = ["//visibility:public"],
)
# iOS device ARM64E.
config_setting(
name = "ios_arm64e",
constraint_values = [
"@platforms//os:ios",
"@platforms//cpu:arm64e",
],
visibility = ["//visibility:public"],
)
# iOS simulator x86 32-bit.
config_setting(
name = "ios_i386",
constraint_values = [
"@platforms//os:ios",
"@platforms//cpu:x86_32",
"@build_bazel_apple_support//constraints:simulator",
],
visibility = ["//visibility:public"],
)
# iOS simulator x86 64-bit.
config_setting(
name = "ios_x86_64",
constraint_values = [
"@platforms//os:ios",
"@platforms//cpu:x86_64",
"@build_bazel_apple_support//constraints:simulator",
],
visibility = ["//visibility:public"],
)
# iOS simulator ARM64.
config_setting(
name = "ios_sim_arm64",
constraint_values = [
"@platforms//os:ios",
"@platforms//cpu:arm64",
"@build_bazel_apple_support//constraints:simulator",
],
visibility = ["//visibility:public"],
)
# Generic Apple.
alias(
name = "apple",
actual = select({
@@ -102,48 +180,6 @@ alias(
visibility = ["//visibility:public"],
)
config_setting(
name = "macos_i386",
values = {
"apple_platform_type": "macos",
"cpu": "darwin",
},
visibility = ["//visibility:public"],
)
config_setting(
name = "macos_x86_64",
values = {
"apple_platform_type": "macos",
"cpu": "darwin_x86_64",
},
visibility = ["//visibility:public"],
)
config_setting(
name = "macos_arm64",
values = {
"apple_platform_type": "macos",
"cpu": "darwin_arm64",
},
visibility = ["//visibility:public"],
)
[
config_setting(
name = arch,
values = {"cpu": arch},
visibility = ["//visibility:public"],
)
for arch in [
"ios_i386",
"ios_x86_64",
"ios_armv7",
"ios_arm64",
"ios_arm64e",
]
]
config_setting(
name = "windows",
values = {"cpu": "x64_windows"},
+15 -3
View File
@@ -219,12 +219,10 @@ cc_library(
deps = [
":time_series_framer_calculator_cc_proto",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:timestamp",
"//mediapipe/framework/formats:matrix",
"//mediapipe/framework/formats:time_series_header_cc_proto",
"//mediapipe/framework/port:integral_types",
"//mediapipe/framework/port:logging",
"//mediapipe/framework/port:ret_check",
"//mediapipe/framework/port:status",
"//mediapipe/util:time_series_util",
"@com_google_audio_tools//audio/dsp:window_functions",
"@eigen_archive//:eigen3",
@@ -319,6 +317,20 @@ cc_test(
],
)
cc_binary(
name = "time_series_framer_calculator_benchmark",
srcs = ["time_series_framer_calculator_benchmark.cc"],
deps = [
":time_series_framer_calculator",
":time_series_framer_calculator_cc_proto",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:packet",
"//mediapipe/framework/formats:matrix",
"//mediapipe/framework/formats:time_series_header_cc_proto",
"@com_google_benchmark//:benchmark",
],
)
cc_test(
name = "time_series_framer_calculator_test",
srcs = ["time_series_framer_calculator_test.cc"],
@@ -210,6 +210,23 @@ REGISTER_CALCULATOR(SpectrogramCalculator);
// Factor to convert ln(SQUARED_MAGNITUDE) to deciBels = 10.0/ln(10.0).
const float SpectrogramCalculator::kLnSquaredMagnitudeToDb = 4.342944819032518;
namespace {
std::unique_ptr<audio_dsp::WindowFunction> MakeWindowFun(
const SpectrogramCalculatorOptions::WindowType window_type) {
switch (window_type) {
// The cosine window and square root of Hann are equivalent.
case SpectrogramCalculatorOptions::COSINE:
case SpectrogramCalculatorOptions::SQRT_HANN:
return std::make_unique<audio_dsp::CosineWindow>();
case SpectrogramCalculatorOptions::HANN:
return std::make_unique<audio_dsp::HannWindow>();
case SpectrogramCalculatorOptions::HAMMING:
return std::make_unique<audio_dsp::HammingWindow>();
}
return nullptr;
}
} // namespace
absl::Status SpectrogramCalculator::Open(CalculatorContext* cc) {
SpectrogramCalculatorOptions spectrogram_options =
cc->Options<SpectrogramCalculatorOptions>();
@@ -266,28 +283,14 @@ absl::Status SpectrogramCalculator::Open(CalculatorContext* cc) {
output_scale_ = spectrogram_options.output_scale();
std::vector<double> window;
switch (spectrogram_options.window_type()) {
case SpectrogramCalculatorOptions::COSINE:
audio_dsp::CosineWindow().GetPeriodicSamples(frame_duration_samples_,
&window);
break;
case SpectrogramCalculatorOptions::HANN:
audio_dsp::HannWindow().GetPeriodicSamples(frame_duration_samples_,
&window);
break;
case SpectrogramCalculatorOptions::HAMMING:
audio_dsp::HammingWindow().GetPeriodicSamples(frame_duration_samples_,
&window);
break;
case SpectrogramCalculatorOptions::SQRT_HANN: {
audio_dsp::HannWindow().GetPeriodicSamples(frame_duration_samples_,
&window);
absl::c_transform(window, window.begin(),
[](double x) { return std::sqrt(x); });
break;
}
auto window_fun = MakeWindowFun(spectrogram_options.window_type());
if (window_fun == nullptr) {
return absl::Status(absl::StatusCode::kInvalidArgument,
absl::StrCat("Invalid window type ",
spectrogram_options.window_type()));
}
std::vector<double> window;
window_fun->GetPeriodicSamples(frame_duration_samples_, &window);
// Propagate settings down to the actual Spectrogram object.
spectrogram_generators_.clear();
@@ -433,9 +436,9 @@ absl::Status SpectrogramCalculator::ProcessVectorToOutput(
absl::Status SpectrogramCalculator::ProcessVector(const Matrix& input_stream,
CalculatorContext* cc) {
switch (output_type_) {
// These blocks deliberately ignore clang-format to preserve the
// "silhouette" of the different cases.
// clang-format off
// These blocks deliberately ignore clang-format to preserve the
// "silhouette" of the different cases.
// clang-format off
case SpectrogramCalculatorOptions::COMPLEX: {
return ProcessVectorToOutput(
input_stream,
@@ -68,7 +68,7 @@ message SpectrogramCalculatorOptions {
HANN = 0;
HAMMING = 1;
COSINE = 2;
SQRT_HANN = 4;
SQRT_HANN = 4; // Alias of COSINE.
}
optional WindowType window_type = 6 [default = HANN];
@@ -15,9 +15,7 @@
// Defines TimeSeriesFramerCalculator.
#include <math.h>
#include <deque>
#include <memory>
#include <string>
#include <vector>
#include "Eigen/Core"
#include "audio/dsp/window_functions.h"
@@ -25,9 +23,8 @@
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/formats/matrix.h"
#include "mediapipe/framework/formats/time_series_header.pb.h"
#include "mediapipe/framework/port/integral_types.h"
#include "mediapipe/framework/port/logging.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/framework/timestamp.h"
#include "mediapipe/util/time_series_util.h"
namespace mediapipe {
@@ -88,11 +85,6 @@ class TimeSeriesFramerCalculator : public CalculatorBase {
absl::Status Close(CalculatorContext* cc) override;
private:
// Adds input data to the internal buffer.
void EnqueueInput(CalculatorContext* cc);
// Constructs and emits framed output packets.
void FrameOutput(CalculatorContext* cc);
Timestamp CurrentOutputTimestamp() {
if (use_local_timestamp_) {
return current_timestamp_;
@@ -106,14 +98,6 @@ class TimeSeriesFramerCalculator : public CalculatorBase {
Timestamp::kTimestampUnitsPerSecond);
}
// Returns the timestamp of a sample on a base, which is usually the time
// stamp of a packet.
Timestamp CurrentSampleTimestamp(const Timestamp& timestamp_base,
int64_t number_of_samples) {
return timestamp_base + round(number_of_samples / sample_rate_ *
Timestamp::kTimestampUnitsPerSecond);
}
// The number of input samples to advance after the current output frame is
// emitted.
int next_frame_step_samples() const {
@@ -142,61 +126,174 @@ class TimeSeriesFramerCalculator : public CalculatorBase {
Timestamp initial_input_timestamp_;
// The current timestamp is updated along with the incoming packets.
Timestamp current_timestamp_;
int num_channels_;
// Each entry in this deque consists of a single sample, i.e. a
// single column vector, and its timestamp.
std::deque<std::pair<Matrix, Timestamp>> sample_buffer_;
// Samples are buffered in a vector of sample blocks.
class SampleBlockBuffer {
public:
// Initializes the buffer.
void Init(double sample_rate, int num_channels) {
ts_units_per_sample_ = Timestamp::kTimestampUnitsPerSecond / sample_rate;
num_channels_ = num_channels;
num_samples_ = 0;
first_block_offset_ = 0;
}
// Number of channels, equal to the number of rows in each Matrix.
int num_channels() const { return num_channels_; }
// Total number of available samples over all blocks.
int num_samples() const { return num_samples_; }
// Pushes a new block of samples on the back of the buffer with `timestamp`
// being the input timestamp of the packet containing the Matrix.
void Push(const Matrix& samples, Timestamp timestamp);
// Copies `count` samples from the front of the buffer. If there are fewer
// samples than this, the result is zero padded to have `count` samples.
// The timestamp of the last copied sample is written to *last_timestamp.
// This output is used below to update `current_timestamp_`, which is only
// used when `use_local_timestamp` is true.
Matrix CopySamples(int count, Timestamp* last_timestamp) const;
// Drops `count` samples from the front of the buffer. If `count` exceeds
// `num_samples()`, the buffer is emptied. Returns how many samples were
// dropped.
int DropSamples(int count);
private:
struct Block {
// Matrix of num_channels rows by num_samples columns, a block of possibly
// multiple samples.
Matrix samples;
// Timestamp of the first sample in the Block. This comes from the input
// packet's timestamp that contains this Matrix.
Timestamp timestamp;
Block() : timestamp(Timestamp::Unstarted()) {}
Block(const Matrix& samples, Timestamp timestamp)
: samples(samples), timestamp(timestamp) {}
int num_samples() const { return samples.cols(); }
};
std::vector<Block> blocks_;
// Number of timestamp units per sample. Used to compute timestamps as
// nth sample timestamp = base_timestamp + round(ts_units_per_sample_ * n).
double ts_units_per_sample_;
// Number of rows in each Matrix.
int num_channels_;
// The total number of samples over all blocks, equal to
// (sum_i blocks_[i].num_samples()) - first_block_offset_.
int num_samples_;
// The number of samples in the first block that have been discarded. This
// way we can cheaply represent "partially discarding" a block.
int first_block_offset_;
} sample_buffer_;
bool use_window_;
Matrix window_;
Eigen::RowVectorXf window_;
bool use_local_timestamp_;
};
REGISTER_CALCULATOR(TimeSeriesFramerCalculator);
void TimeSeriesFramerCalculator::EnqueueInput(CalculatorContext* cc) {
const Matrix& input_frame = cc->Inputs().Index(0).Get<Matrix>();
for (int i = 0; i < input_frame.cols(); ++i) {
sample_buffer_.emplace_back(std::make_pair(
input_frame.col(i), CurrentSampleTimestamp(cc->InputTimestamp(), i)));
}
void TimeSeriesFramerCalculator::SampleBlockBuffer::Push(const Matrix& samples,
Timestamp timestamp) {
num_samples_ += samples.cols();
blocks_.emplace_back(samples, timestamp);
}
void TimeSeriesFramerCalculator::FrameOutput(CalculatorContext* cc) {
while (sample_buffer_.size() >=
Matrix TimeSeriesFramerCalculator::SampleBlockBuffer::CopySamples(
int count, Timestamp* last_timestamp) const {
Matrix copied(num_channels_, count);
if (!blocks_.empty()) {
int num_copied = 0;
// First block has an offset for samples that have been discarded.
int offset = first_block_offset_;
int n;
Timestamp last_block_ts;
int last_sample_index;
for (auto it = blocks_.begin(); it != blocks_.end() && count > 0; ++it) {
n = std::min(it->num_samples() - offset, count);
// Copy `n` samples from the next block.
copied.middleCols(num_copied, n) = it->samples.middleCols(offset, n);
count -= n;
num_copied += n;
last_block_ts = it->timestamp;
last_sample_index = offset + n - 1;
offset = 0; // No samples have been discarded in subsequent blocks.
}
// Compute the timestamp of the last copied sample.
*last_timestamp =
last_block_ts + std::round(ts_units_per_sample_ * last_sample_index);
}
if (count > 0) {
copied.rightCols(count).setZero(); // Zero pad if needed.
}
return copied;
}
int TimeSeriesFramerCalculator::SampleBlockBuffer::DropSamples(int count) {
if (blocks_.empty()) {
return 0;
}
auto block_it = blocks_.begin();
if (first_block_offset_ + count < block_it->num_samples()) {
// `count` is less than the remaining samples in the first block.
first_block_offset_ += count;
num_samples_ -= count;
return count;
}
int num_samples_dropped = block_it->num_samples() - first_block_offset_;
count -= num_samples_dropped;
first_block_offset_ = 0;
for (++block_it; block_it != blocks_.end(); ++block_it) {
if (block_it->num_samples() > count) {
break;
}
num_samples_dropped += block_it->num_samples();
count -= block_it->num_samples();
}
blocks_.erase(blocks_.begin(), block_it); // Drop whole blocks.
if (!blocks_.empty()) {
first_block_offset_ = count; // Drop part of the next block.
num_samples_dropped += count;
}
num_samples_ -= num_samples_dropped;
return num_samples_dropped;
}
absl::Status TimeSeriesFramerCalculator::Process(CalculatorContext* cc) {
if (initial_input_timestamp_ == Timestamp::Unstarted()) {
initial_input_timestamp_ = cc->InputTimestamp();
current_timestamp_ = initial_input_timestamp_;
}
// Add input data to the internal buffer.
sample_buffer_.Push(cc->Inputs().Index(0).Get<Matrix>(),
cc->InputTimestamp());
// Construct and emit framed output packets.
while (sample_buffer_.num_samples() >=
frame_duration_samples_ + samples_still_to_drop_) {
while (samples_still_to_drop_ > 0) {
sample_buffer_.pop_front();
--samples_still_to_drop_;
}
sample_buffer_.DropSamples(samples_still_to_drop_);
Matrix output_frame = sample_buffer_.CopySamples(frame_duration_samples_,
&current_timestamp_);
const int frame_step_samples = next_frame_step_samples();
std::unique_ptr<Matrix> output_frame(
new Matrix(num_channels_, frame_duration_samples_));
for (int i = 0; i < std::min(frame_step_samples, frame_duration_samples_);
++i) {
output_frame->col(i) = sample_buffer_.front().first;
current_timestamp_ = sample_buffer_.front().second;
sample_buffer_.pop_front();
}
const int frame_overlap_samples =
frame_duration_samples_ - frame_step_samples;
if (frame_overlap_samples > 0) {
for (int i = 0; i < frame_overlap_samples; ++i) {
output_frame->col(i + frame_step_samples) = sample_buffer_[i].first;
current_timestamp_ = sample_buffer_[i].second;
}
} else {
samples_still_to_drop_ = -frame_overlap_samples;
}
samples_still_to_drop_ = frame_step_samples;
if (use_window_) {
*output_frame = (output_frame->array() * window_.array()).matrix();
// Apply the window to each row of output_frame.
output_frame.array().rowwise() *= window_.array();
}
cc->Outputs().Index(0).Add(output_frame.release(),
CurrentOutputTimestamp());
cc->Outputs().Index(0).AddPacket(MakePacket<Matrix>(std::move(output_frame))
.At(CurrentOutputTimestamp()));
++cumulative_output_frames_;
cumulative_completed_samples_ += frame_step_samples;
}
@@ -206,35 +303,18 @@ void TimeSeriesFramerCalculator::FrameOutput(CalculatorContext* cc) {
// fact to enable packet queueing optimizations.
cc->Outputs().Index(0).SetNextTimestampBound(CumulativeOutputTimestamp());
}
}
absl::Status TimeSeriesFramerCalculator::Process(CalculatorContext* cc) {
if (initial_input_timestamp_ == Timestamp::Unstarted()) {
initial_input_timestamp_ = cc->InputTimestamp();
current_timestamp_ = initial_input_timestamp_;
}
EnqueueInput(cc);
FrameOutput(cc);
return absl::OkStatus();
}
absl::Status TimeSeriesFramerCalculator::Close(CalculatorContext* cc) {
while (samples_still_to_drop_ > 0 && !sample_buffer_.empty()) {
sample_buffer_.pop_front();
--samples_still_to_drop_;
}
if (!sample_buffer_.empty() && pad_final_packet_) {
std::unique_ptr<Matrix> output_frame(new Matrix);
output_frame->setZero(num_channels_, frame_duration_samples_);
for (int i = 0; i < sample_buffer_.size(); ++i) {
output_frame->col(i) = sample_buffer_[i].first;
current_timestamp_ = sample_buffer_[i].second;
}
sample_buffer_.DropSamples(samples_still_to_drop_);
cc->Outputs().Index(0).Add(output_frame.release(),
CurrentOutputTimestamp());
if (sample_buffer_.num_samples() > 0 && pad_final_packet_) {
Matrix output_frame = sample_buffer_.CopySamples(frame_duration_samples_,
&current_timestamp_);
cc->Outputs().Index(0).AddPacket(MakePacket<Matrix>(std::move(output_frame))
.At(CurrentOutputTimestamp()));
}
return absl::OkStatus();
@@ -258,7 +338,7 @@ absl::Status TimeSeriesFramerCalculator::Open(CalculatorContext* cc) {
cc->Inputs().Index(0).Header(), &input_header));
sample_rate_ = input_header.sample_rate();
num_channels_ = input_header.num_channels();
sample_buffer_.Init(sample_rate_, input_header.num_channels());
frame_duration_samples_ = time_series_util::SecondsToSamples(
framer_options.frame_duration_seconds(), sample_rate_);
RET_CHECK_GT(frame_duration_samples_, 0)
@@ -312,9 +392,8 @@ absl::Status TimeSeriesFramerCalculator::Open(CalculatorContext* cc) {
}
if (use_window_) {
window_ = Matrix::Ones(num_channels_, 1) *
Eigen::Map<Eigen::MatrixXd>(window_vector.data(), 1,
frame_duration_samples_)
window_ = Eigen::Map<Eigen::RowVectorXd>(window_vector.data(),
frame_duration_samples_)
.cast<float>();
}
use_local_timestamp_ = framer_options.use_local_timestamp();
@@ -0,0 +1,92 @@
// 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.
//
// Benchmark for TimeSeriesFramerCalculator.
#include <memory>
#include <random>
#include <vector>
#include "benchmark/benchmark.h"
#include "mediapipe/calculators/audio/time_series_framer_calculator.pb.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/formats/matrix.h"
#include "mediapipe/framework/formats/time_series_header.pb.h"
#include "mediapipe/framework/packet.h"
using ::mediapipe::Matrix;
void BM_TimeSeriesFramerCalculator(benchmark::State& state) {
constexpr float kSampleRate = 32000.0;
constexpr int kNumChannels = 2;
constexpr int kFrameDurationSeconds = 5.0;
std::mt19937 rng(0 /*seed*/);
// Input around a half second's worth of samples at a time.
std::uniform_int_distribution<int> input_size_dist(15000, 17000);
// Generate a pool of random blocks of samples up front.
std::vector<Matrix> sample_pool;
sample_pool.reserve(20);
for (int i = 0; i < 20; ++i) {
sample_pool.push_back(Matrix::Random(kNumChannels, input_size_dist(rng)));
}
std::uniform_int_distribution<int> pool_index_dist(0, sample_pool.size() - 1);
mediapipe::CalculatorGraphConfig config;
config.add_input_stream("input");
config.add_output_stream("output");
auto* node = config.add_node();
node->set_calculator("TimeSeriesFramerCalculator");
node->add_input_stream("input");
node->add_output_stream("output");
mediapipe::TimeSeriesFramerCalculatorOptions* options =
node->mutable_options()->MutableExtension(
mediapipe::TimeSeriesFramerCalculatorOptions::ext);
options->set_frame_duration_seconds(kFrameDurationSeconds);
for (auto _ : state) {
state.PauseTiming(); // Pause benchmark timing.
// Prepare input packets of random blocks of samples.
std::vector<mediapipe::Packet> input_packets;
input_packets.reserve(32);
float t = 0;
for (int i = 0; i < 32; ++i) {
auto samples =
std::make_unique<Matrix>(sample_pool[pool_index_dist(rng)]);
const int num_samples = samples->cols();
input_packets.push_back(mediapipe::Adopt(samples.release())
.At(mediapipe::Timestamp::FromSeconds(t)));
t += num_samples / kSampleRate;
}
// Initialize graph.
mediapipe::CalculatorGraph graph;
CHECK_OK(graph.Initialize(config));
// Prepare input header.
auto header = std::make_unique<mediapipe::TimeSeriesHeader>();
header->set_sample_rate(kSampleRate);
header->set_num_channels(kNumChannels);
state.ResumeTiming(); // Resume benchmark timing.
CHECK_OK(graph.StartRun({}, {{"input", Adopt(header.release())}}));
for (auto& packet : input_packets) {
CHECK_OK(graph.AddPacketToInputStream("input", packet));
}
CHECK(!graph.HasError());
CHECK_OK(graph.CloseAllInputStreams());
CHECK_OK(graph.WaitUntilIdle());
}
}
BENCHMARK(BM_TimeSeriesFramerCalculator);
BENCHMARK_MAIN();
+14 -18
View File
@@ -117,6 +117,7 @@ mediapipe_proto_library(
"//mediapipe/framework:calculator_proto",
"//mediapipe/framework/formats:classification_proto",
"//mediapipe/framework/formats:landmark_proto",
"//mediapipe/framework/formats:matrix_data_proto",
"//mediapipe/framework/formats:time_series_header_proto",
],
)
@@ -192,17 +193,19 @@ cc_library(
"//mediapipe/framework:calculator_context",
"//mediapipe/framework:calculator_contract",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:collection_item_id",
"//mediapipe/framework:packet",
"//mediapipe/framework/formats:detection_cc_proto",
"//mediapipe/framework/formats:image",
"//mediapipe/framework/formats:image_frame",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:matrix",
"//mediapipe/framework/formats:rect_cc_proto",
"//mediapipe/framework/formats:tensor",
"//mediapipe/framework/port:integral_types",
"//mediapipe/framework/port:ret_check",
"//mediapipe/framework/port:status",
"//mediapipe/gpu:gpu_buffer",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/status",
],
alwayslink = 1,
)
@@ -215,18 +218,18 @@ cc_library(
"//mediapipe/framework:calculator_context",
"//mediapipe/framework:calculator_contract",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:collection_item_id",
"//mediapipe/framework/formats:classification_cc_proto",
"//mediapipe/framework/formats:detection_cc_proto",
"//mediapipe/framework/formats:image",
"//mediapipe/framework/formats:image_frame",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:matrix",
"//mediapipe/framework/formats:rect_cc_proto",
"//mediapipe/framework/formats:tensor",
"//mediapipe/framework/port:integral_types",
"//mediapipe/framework/port:ret_check",
"//mediapipe/framework/port:status",
"//mediapipe/gpu:gpu_buffer",
"//mediapipe/util:render_data_cc_proto",
"@com_google_absl//absl/status",
"@org_tensorflow//tensorflow/lite:framework",
],
alwayslink = 1,
@@ -287,6 +290,7 @@ cc_library(
"//mediapipe/framework/api2:node",
"//mediapipe/framework/api2:port",
"//mediapipe/framework/formats:classification_cc_proto",
"//mediapipe/framework/formats:image",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:tensor",
"//mediapipe/framework/port:integral_types",
@@ -295,8 +299,7 @@ cc_library(
"//mediapipe/util:render_data_cc_proto",
"@org_tensorflow//tensorflow/lite:framework",
] + select({
"//mediapipe/gpu:disable_gpu": [],
"//mediapipe:ios": [],
":ios_or_disable_gpu": [],
"//conditions:default": [
"@org_tensorflow//tensorflow/lite/delegates/gpu/gl:gl_buffer",
],
@@ -378,17 +381,6 @@ cc_library(
alwayslink = 1,
)
cc_library(
name = "clip_detection_vector_size_calculator",
srcs = ["clip_detection_vector_size_calculator.cc"],
deps = [
":clip_vector_size_calculator",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework/formats:detection_cc_proto",
],
alwayslink = 1,
)
cc_test(
name = "clip_vector_size_calculator_test",
srcs = ["clip_vector_size_calculator_test.cc"],
@@ -904,6 +896,7 @@ cc_library(
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework/formats:classification_cc_proto",
"//mediapipe/framework/formats:detection_cc_proto",
"//mediapipe/framework/formats:image",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:matrix",
"//mediapipe/framework/formats:rect_cc_proto",
@@ -1136,6 +1129,7 @@ cc_library(
deps = [
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:timestamp",
"//mediapipe/framework/api2:node",
"//mediapipe/framework/port:status",
],
alwayslink = 1,
@@ -1164,6 +1158,7 @@ cc_library(
"//mediapipe/framework:collection_item_id",
"//mediapipe/framework/formats:classification_cc_proto",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:matrix_data_cc_proto",
"//mediapipe/framework/formats:time_series_header_cc_proto",
"//mediapipe/framework/port:integral_types",
"//mediapipe/framework/port:ret_check",
@@ -1238,6 +1233,7 @@ cc_library(
"//mediapipe/framework/formats:classification_cc_proto",
"//mediapipe/framework/formats:detection_cc_proto",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:rect_cc_proto",
"//mediapipe/framework/port:ret_check",
"//mediapipe/framework/port:status",
],
@@ -17,10 +17,13 @@
#include <vector>
#include "mediapipe/framework/formats/detection.pb.h"
#include "mediapipe/framework/formats/image.h"
#include "mediapipe/framework/formats/image_frame.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/matrix.h"
#include "mediapipe/framework/formats/rect.pb.h"
#include "mediapipe/framework/formats/tensor.h"
#include "mediapipe/gpu/gpu_buffer.h"
namespace mediapipe {
@@ -60,4 +63,22 @@ REGISTER_CALCULATOR(BeginLoopUint64tCalculator);
typedef BeginLoopCalculator<std::vector<Tensor>> BeginLoopTensorCalculator;
REGISTER_CALCULATOR(BeginLoopTensorCalculator);
// A calculator to process std::vector<mediapipe::ImageFrame>.
typedef BeginLoopCalculator<std::vector<ImageFrame>>
BeginLoopImageFrameCalculator;
REGISTER_CALCULATOR(BeginLoopImageFrameCalculator);
// A calculator to process std::vector<mediapipe::GpuBuffer>.
typedef BeginLoopCalculator<std::vector<GpuBuffer>>
BeginLoopGpuBufferCalculator;
REGISTER_CALCULATOR(BeginLoopGpuBufferCalculator);
// A calculator to process std::vector<mediapipe::Image>.
typedef BeginLoopCalculator<std::vector<Image>> BeginLoopImageCalculator;
REGISTER_CALCULATOR(BeginLoopImageCalculator);
// A calculator to process std::vector<float>.
typedef BeginLoopCalculator<std::vector<float>> BeginLoopFloatCalculator;
REGISTER_CALCULATOR(BeginLoopFloatCalculator);
} // namespace mediapipe
@@ -15,47 +15,57 @@
#ifndef MEDIAPIPE_CALCULATORS_CORE_BEGIN_LOOP_CALCULATOR_H_
#define MEDIAPIPE_CALCULATORS_CORE_BEGIN_LOOP_CALCULATOR_H_
#include "absl/status/status.h"
#include "mediapipe/framework/calculator_context.h"
#include "mediapipe/framework/calculator_contract.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/collection_item_id.h"
#include "mediapipe/framework/packet.h"
#include "mediapipe/framework/port/integral_types.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/framework/port/status.h"
#include "mediapipe/framework/port/status_macros.h"
namespace mediapipe {
// Calculator for implementing loops on iterable collections inside a MediaPipe
// graph.
// graph. Assume InputIterT is an iterable for type InputT, and OutputIterT is
// an iterable for type OutputT, e.g. vector<InputT> and vector<OutputT>.
// First, instantiate specializations in the loop calculators' implementations
// if missing:
// BeginLoopInputTCalculator = BeginLoopCalculator<InputIterT>
// EndLoopOutputTCalculator = EndLoopCalculator<OutputIterT>
// Then, the following graph transforms an item of type InputIterT to an
// OutputIterT by applying InputToOutputConverter to every element:
//
// It is designed to be used like:
//
// node {
// calculator: "BeginLoopWithIterableCalculator"
// input_stream: "ITERABLE:input_iterable" # IterableT @ext_ts
// output_stream: "ITEM:input_element" # ItemT @loop_internal_ts
// output_stream: "BATCH_END:ext_ts" # Timestamp @loop_internal_ts
// node { # Type @timestamp
// calculator: "BeginLoopInputTCalculator"
// input_stream: "ITERABLE:input_iterable" # InputIterT @iterable_ts
// input_stream: "CLONE:extra_input" # ExtraT @extra_ts
// output_stream: "ITEM:input_iterator" # InputT @loop_internal_ts
// output_stream: "CLONE:cloned_extra_input" # ExtraT @loop_internal_ts
// output_stream: "BATCH_END:iterable_ts" # Timestamp @loop_internal_ts
// }
//
// node {
// calculator: "ElementToBlaConverterSubgraph"
// input_stream: "ITEM:input_to_loop_body" # ItemT @loop_internal_ts
// output_stream: "BLA:output_of_loop_body" # ItemU @loop_internal_ts
// calculator: "InputToOutputConverter"
// input_stream: "INPUT:input_iterator" # InputT @loop_internal_ts
// input_stream: "EXTRA:cloned_extra_input" # ExtraT @loop_internal_ts
// output_stream: "OUTPUT:output_iterator" # OutputT @loop_internal_ts
// }
//
// node {
// calculator: "EndLoopWithOutputCalculator"
// input_stream: "ITEM:output_of_loop_body" # ItemU @loop_internal_ts
// input_stream: "BATCH_END:ext_ts" # Timestamp @loop_internal_ts
// output_stream: "ITERABLE:aggregated_result" # IterableU @ext_ts
// calculator: "EndLoopOutputTCalculator"
// input_stream: "ITEM:output_iterator" # OutputT @loop_internal_ts
// input_stream: "BATCH_END:iterable_ts" # Timestamp @loop_internal_ts
// output_stream: "ITERABLE:output_iterable" # OutputIterT @iterable_ts
// }
//
// The resulting 'output_iterable' has the same timestamp as 'input_iterable'.
// The output packets of this calculator are part of the loop body and have
// loop-internal timestamps that are unrelated to the input iterator timestamp.
//
// Input streams tagged with "CLONE" are cloned to the corresponding output
// streams at loop timestamps. This ensures that a MediaPipe graph or sub-graph
// can run multiple times, once per element in the "ITERABLE" for each pakcet
// clone of the packets in the "CLONE" input streams.
// streams at loop-internal timestamps. This ensures that a MediaPipe graph or
// sub-graph can run multiple times, once per element in the "ITERABLE" for each
// packet clone of the packets in the "CLONE" input streams. Think of CLONEd
// inputs as loop-wide constants.
template <typename IterableT>
class BeginLoopCalculator : public CalculatorBase {
using ItemT = typename IterableT::value_type;
@@ -17,6 +17,7 @@
#include <vector>
#include "mediapipe/framework/formats/classification.pb.h"
#include "mediapipe/framework/formats/image.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/tensor.h"
#include "mediapipe/framework/port/integral_types.h"
@@ -55,6 +56,10 @@ MEDIAPIPE_REGISTER_NODE(ConcatenateUInt64VectorCalculator);
typedef ConcatenateVectorCalculator<bool> ConcatenateBoolVectorCalculator;
MEDIAPIPE_REGISTER_NODE(ConcatenateBoolVectorCalculator);
typedef ConcatenateVectorCalculator<std::string>
ConcatenateStringVectorCalculator;
MEDIAPIPE_REGISTER_NODE(ConcatenateStringVectorCalculator);
// Example config:
// node {
// calculator: "ConcatenateTfLiteTensorVectorCalculator"
@@ -100,4 +105,7 @@ typedef ConcatenateVectorCalculator<mediapipe::RenderData>
ConcatenateRenderDataVectorCalculator;
MEDIAPIPE_REGISTER_NODE(ConcatenateRenderDataVectorCalculator);
typedef ConcatenateVectorCalculator<mediapipe::Image>
ConcatenateImageVectorCalculator;
MEDIAPIPE_REGISTER_NODE(ConcatenateImageVectorCalculator);
} // namespace mediapipe
@@ -30,13 +30,15 @@ namespace mediapipe {
typedef ConcatenateVectorCalculator<int> TestConcatenateIntVectorCalculator;
MEDIAPIPE_REGISTER_NODE(TestConcatenateIntVectorCalculator);
void AddInputVector(int index, const std::vector<int>& input, int64_t timestamp,
template <typename T>
void AddInputVector(int index, const std::vector<T>& input, int64_t timestamp,
CalculatorRunner* runner) {
runner->MutableInputs()->Index(index).packets.push_back(
MakePacket<std::vector<int>>(input).At(Timestamp(timestamp)));
MakePacket<std::vector<T>>(input).At(Timestamp(timestamp)));
}
void AddInputVectors(const std::vector<std::vector<int>>& inputs,
template <typename T>
void AddInputVectors(const std::vector<std::vector<T>>& inputs,
int64_t timestamp, CalculatorRunner* runner) {
for (int i = 0; i < inputs.size(); ++i) {
AddInputVector(i, inputs[i], timestamp, runner);
@@ -382,6 +384,23 @@ TEST(ConcatenateFloatVectorCalculatorTest, OneEmptyStreamNoOutput) {
EXPECT_EQ(0, outputs.size());
}
TEST(ConcatenateStringVectorCalculatorTest, OneTimestamp) {
CalculatorRunner runner("ConcatenateStringVectorCalculator",
/*options_string=*/"", /*num_inputs=*/3,
/*num_outputs=*/1, /*num_side_packets=*/0);
std::vector<std::vector<std::string>> inputs = {
{"a", "b"}, {"c"}, {"d", "e", "f"}};
AddInputVectors(inputs, /*timestamp=*/1, &runner);
MP_ASSERT_OK(runner.Run());
const std::vector<Packet>& outputs = runner.Outputs().Index(0).packets;
EXPECT_EQ(1, outputs.size());
EXPECT_EQ(Timestamp(1), outputs[0].Timestamp());
std::vector<std::string> expected_vector = {"a", "b", "c", "d", "e", "f"};
EXPECT_EQ(expected_vector, outputs[0].Get<std::vector<std::string>>());
}
typedef ConcatenateVectorCalculator<std::unique_ptr<int>>
TestConcatenateUniqueIntPtrCalculator;
MEDIAPIPE_REGISTER_NODE(TestConcatenateUniqueIntPtrCalculator);
@@ -19,6 +19,7 @@
#include "mediapipe/framework/collection_item_id.h"
#include "mediapipe/framework/formats/classification.pb.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/matrix_data.pb.h"
#include "mediapipe/framework/formats/time_series_header.pb.h"
#include "mediapipe/framework/port/canonical_errors.h"
#include "mediapipe/framework/port/integral_types.h"
@@ -85,8 +86,12 @@ class ConstantSidePacketCalculator : public CalculatorBase {
packet.Set<LandmarkList>();
} else if (packet_options.has_double_value()) {
packet.Set<double>();
} else if (packet_options.has_matrix_data_value()) {
packet.Set<MatrixData>();
} else if (packet_options.has_time_series_header_value()) {
packet.Set<TimeSeriesHeader>();
} else if (packet_options.has_int64_value()) {
packet.Set<int64_t>();
} else {
return absl::InvalidArgumentError(
"None of supported values were specified in options.");
@@ -121,9 +126,13 @@ class ConstantSidePacketCalculator : public CalculatorBase {
MakePacket<LandmarkList>(packet_options.landmark_list_value()));
} else if (packet_options.has_double_value()) {
packet.Set(MakePacket<double>(packet_options.double_value()));
} else if (packet_options.has_matrix_data_value()) {
packet.Set(MakePacket<MatrixData>(packet_options.matrix_data_value()));
} else if (packet_options.has_time_series_header_value()) {
packet.Set(MakePacket<TimeSeriesHeader>(
packet_options.time_series_header_value()));
} else if (packet_options.has_int64_value()) {
packet.Set(MakePacket<int64_t>(packet_options.int64_value()));
} else {
return absl::InvalidArgumentError(
"None of supported values were specified in options.");
@@ -19,6 +19,7 @@ package mediapipe;
import "mediapipe/framework/calculator.proto";
import "mediapipe/framework/formats/classification.proto";
import "mediapipe/framework/formats/landmark.proto";
import "mediapipe/framework/formats/matrix_data.proto";
import "mediapipe/framework/formats/time_series_header.proto";
message ConstantSidePacketCalculatorOptions {
@@ -29,14 +30,16 @@ message ConstantSidePacketCalculatorOptions {
message ConstantSidePacket {
oneof value {
int32 int_value = 1;
uint64 uint64_value = 5;
int64 int64_value = 11;
float float_value = 2;
double double_value = 9;
bool bool_value = 3;
string string_value = 4;
uint64 uint64_value = 5;
ClassificationList classification_list_value = 6;
LandmarkList landmark_list_value = 7;
double double_value = 9;
TimeSeriesHeader time_series_header_value = 10;
MatrixData matrix_data_value = 12;
}
}
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cstdint>
#include <string>
#include "absl/strings/string_view.h"
@@ -58,6 +59,7 @@ TEST(ConstantSidePacketCalculatorTest, EveryPossibleType) {
DoTestSingleSidePacket("{ float_value: 6.5f }", 6.5f);
DoTestSingleSidePacket("{ bool_value: true }", true);
DoTestSingleSidePacket<std::string>(R"({ string_value: "str" })", "str");
DoTestSingleSidePacket<int64_t>("{ int64_value: 63 }", 63);
}
TEST(ConstantSidePacketCalculatorTest, MultiplePackets) {
@@ -19,10 +19,12 @@
#include "mediapipe/framework/formats/classification.pb.h"
#include "mediapipe/framework/formats/detection.pb.h"
#include "mediapipe/framework/formats/image.h"
#include "mediapipe/framework/formats/image_frame.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/matrix.h"
#include "mediapipe/framework/formats/rect.pb.h"
#include "mediapipe/framework/formats/tensor.h"
#include "mediapipe/gpu/gpu_buffer.h"
#include "mediapipe/util/render_data.pb.h"
#include "tensorflow/lite/interpreter.h"
@@ -68,8 +70,18 @@ REGISTER_CALCULATOR(EndLoopMatrixCalculator);
typedef EndLoopCalculator<std::vector<Tensor>> EndLoopTensorCalculator;
REGISTER_CALCULATOR(EndLoopTensorCalculator);
typedef EndLoopCalculator<std::vector<ImageFrame>> EndLoopImageFrameCalculator;
REGISTER_CALCULATOR(EndLoopImageFrameCalculator);
typedef EndLoopCalculator<std::vector<GpuBuffer>> EndLoopGpuBufferCalculator;
REGISTER_CALCULATOR(EndLoopGpuBufferCalculator);
typedef EndLoopCalculator<std::vector<::mediapipe::Image>>
EndLoopImageCalculator;
REGISTER_CALCULATOR(EndLoopImageCalculator);
typedef EndLoopCalculator<std::vector<std::array<float, 16>>>
EndLoopAffineMatrixCalculator;
REGISTER_CALCULATOR(EndLoopAffineMatrixCalculator);
} // namespace mediapipe
@@ -17,13 +17,11 @@
#include <type_traits>
#include "absl/status/status.h"
#include "mediapipe/framework/calculator_context.h"
#include "mediapipe/framework/calculator_contract.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/collection_item_id.h"
#include "mediapipe/framework/port/integral_types.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/framework/port/status.h"
namespace mediapipe {
@@ -33,27 +31,7 @@ namespace mediapipe {
// from the "BATCH_END" tagged input stream, it emits the aggregated results
// at the original timestamp contained in the "BATCH_END" input stream.
//
// It is designed to be used like:
//
// node {
// calculator: "BeginLoopWithIterableCalculator"
// input_stream: "ITERABLE:input_iterable" # IterableT @ext_ts
// output_stream: "ITEM:input_element" # ItemT @loop_internal_ts
// output_stream: "BATCH_END:ext_ts" # Timestamp @loop_internal_ts
// }
//
// node {
// calculator: "ElementToBlaConverterSubgraph"
// input_stream: "ITEM:input_to_loop_body" # ItemT @loop_internal_ts
// output_stream: "BLA:output_of_loop_body" # ItemU @loop_internal_ts
// }
//
// node {
// calculator: "EndLoopWithOutputCalculator"
// input_stream: "ITEM:output_of_loop_body" # ItemU @loop_internal_ts
// input_stream: "BATCH_END:ext_ts" # Timestamp @loop_internal_ts
// output_stream: "ITERABLE:aggregated_result" # IterableU @ext_ts
// }
// See BeginLoopCalculator for a usage example.
template <typename IterableT>
class EndLoopCalculator : public CalculatorBase {
using ItemT = typename IterableT::value_type;
@@ -79,7 +57,7 @@ class EndLoopCalculator : public CalculatorBase {
}
// Try to consume the item and move it into the collection. If the items
// are not consumable, then try to copy them instead. If the items are
// not copiable, then an error will be returned.
// not copyable, then an error will be returned.
auto item_ptr_or = cc->Inputs().Tag("ITEM").Value().Consume<ItemT>();
if (item_ptr_or.ok()) {
input_stream_collection_->push_back(std::move(*item_ptr_or.value()));
@@ -42,7 +42,7 @@ constexpr char kOptionsTag[] = "OPTIONS";
//
// Increasing `max_in_flight` to 2 or more can yield the better throughput
// when the graph exhibits a high degree of pipeline parallelism. Decreasing
// `max_in_flight` to 0 can yield a better average latency, but at the cost of
// `max_in_queue` to 0 can yield a better average latency, but at the cost of
// lower throughput (lower framerate) due to the time during which the graph
// is idle awaiting the next input frame.
//
+16 -15
View File
@@ -26,19 +26,15 @@ constexpr char kStateChangeTag[] = "STATE_CHANGE";
constexpr char kDisallowTag[] = "DISALLOW";
constexpr char kAllowTag[] = "ALLOW";
enum GateState {
GATE_UNINITIALIZED,
GATE_ALLOW,
GATE_DISALLOW,
};
std::string ToString(GateState state) {
std::string ToString(GateCalculatorOptions::GateState state) {
switch (state) {
case GATE_UNINITIALIZED:
case GateCalculatorOptions::UNSPECIFIED:
return "UNSPECIFIED";
case GateCalculatorOptions::GATE_UNINITIALIZED:
return "UNINITIALIZED";
case GATE_ALLOW:
case GateCalculatorOptions::GATE_ALLOW:
return "ALLOW";
case GATE_DISALLOW:
case GateCalculatorOptions::GATE_DISALLOW:
return "DISALLOW";
}
DLOG(FATAL) << "Unknown GateState";
@@ -153,10 +149,12 @@ class GateCalculator : public CalculatorBase {
cc->SetOffset(TimestampDiff(0));
num_data_streams_ = cc->Inputs().NumEntries("");
last_gate_state_ = GATE_UNINITIALIZED;
RET_CHECK_OK(CopyInputHeadersToOutputs(cc->Inputs(), &cc->Outputs()));
const auto& options = cc->Options<::mediapipe::GateCalculatorOptions>();
last_gate_state_ = options.initial_gate_state();
RET_CHECK_OK(CopyInputHeadersToOutputs(cc->Inputs(), &cc->Outputs()));
empty_packets_as_allow_ = options.empty_packets_as_allow();
if (!use_side_packet_for_allow_disallow_ &&
@@ -184,10 +182,12 @@ class GateCalculator : public CalculatorBase {
allow = !cc->Inputs().Tag(kDisallowTag).Get<bool>();
}
}
const GateState new_gate_state = allow ? GATE_ALLOW : GATE_DISALLOW;
const GateCalculatorOptions::GateState new_gate_state =
allow ? GateCalculatorOptions::GATE_ALLOW
: GateCalculatorOptions::GATE_DISALLOW;
if (cc->Outputs().HasTag(kStateChangeTag)) {
if (last_gate_state_ != GATE_UNINITIALIZED &&
if (last_gate_state_ != GateCalculatorOptions::GATE_UNINITIALIZED &&
last_gate_state_ != new_gate_state) {
VLOG(2) << "State transition in " << cc->NodeName() << " @ "
<< cc->InputTimestamp().Value() << " from "
@@ -223,7 +223,8 @@ class GateCalculator : public CalculatorBase {
}
private:
GateState last_gate_state_ = GATE_UNINITIALIZED;
GateCalculatorOptions::GateState last_gate_state_ =
GateCalculatorOptions::GATE_UNINITIALIZED;
int num_data_streams_;
bool empty_packets_as_allow_;
bool use_side_packet_for_allow_disallow_ = false;
@@ -31,4 +31,13 @@ message GateCalculatorOptions {
// Whether to allow or disallow the input streams to pass when no
// ALLOW/DISALLOW input or side input is specified.
optional bool allow = 2 [default = false];
enum GateState {
UNSPECIFIED = 0;
GATE_UNINITIALIZED = 1;
GATE_ALLOW = 2;
GATE_DISALLOW = 3;
}
optional GateState initial_gate_state = 3 [default = GATE_UNINITIALIZED];
}
@@ -458,5 +458,29 @@ TEST_F(GateCalculatorTest, AllowInitialNoStateTransition) {
ASSERT_EQ(0, output.size());
}
// Must detect allow value for first timestamp as a state change when the
// initial state is set to GATE_DISALLOW.
TEST_F(GateCalculatorTest, StateChangeTriggeredWithInitialGateStateOption) {
SetRunner(R"(
calculator: "GateCalculator"
input_stream: "test_input"
input_stream: "ALLOW:allow"
output_stream: "test_output"
output_stream: "STATE_CHANGE:state_change"
options: {
[mediapipe.GateCalculatorOptions.ext] {
initial_gate_state: GATE_DISALLOW
}
}
)");
constexpr int64_t kTimestampValue0 = 42;
RunTimeStep(kTimestampValue0, "ALLOW", true);
const std::vector<Packet>& output =
runner()->Outputs().Get("STATE_CHANGE", 0).packets;
ASSERT_EQ(1, output.size());
}
} // namespace
} // namespace mediapipe
@@ -17,6 +17,7 @@
#include "mediapipe/framework/formats/classification.pb.h"
#include "mediapipe/framework/formats/detection.pb.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
namespace mediapipe {
namespace api2 {
@@ -37,5 +38,12 @@ using GetDetectionVectorItemCalculator =
GetVectorItemCalculator<mediapipe::Detection>;
REGISTER_CALCULATOR(GetDetectionVectorItemCalculator);
using GetNormalizedRectVectorItemCalculator =
GetVectorItemCalculator<NormalizedRect>;
REGISTER_CALCULATOR(GetNormalizedRectVectorItemCalculator);
using GetRectVectorItemCalculator = GetVectorItemCalculator<Rect>;
REGISTER_CALCULATOR(GetRectVectorItemCalculator);
} // namespace api2
} // namespace mediapipe
@@ -35,7 +35,7 @@ class MatrixToVectorCalculatorTest
void SetUp() override { calculator_name_ = "MatrixToVectorCalculator"; }
void AppendInput(const std::vector<float>& column_major_data,
int64 timestamp) {
int64_t timestamp) {
ASSERT_EQ(num_input_samples_ * num_input_channels_,
column_major_data.size());
Eigen::Map<const Matrix> data_map(&column_major_data[0],
@@ -1,4 +1,4 @@
/* Copyright 2022 The MediaPipe Authors. All Rights Reserved.
/* Copyright 2022 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.
@@ -1,4 +1,4 @@
/* Copyright 2022 The MediaPipe Authors. All Rights Reserved.
/* Copyright 2022 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.
@@ -51,9 +51,9 @@ class SimpleRunner : public CalculatorRunner {
virtual ~SimpleRunner() {}
void SetInput(const std::vector<int64>& timestamp_list) {
void SetInput(const std::vector<int64_t>& timestamp_list) {
MutableInputs()->Index(0).packets.clear();
for (const int64 ts : timestamp_list) {
for (const int64_t ts : timestamp_list) {
MutableInputs()->Index(0).packets.push_back(
Adopt(new std::string(absl::StrCat("Frame #", ts)))
.At(Timestamp(ts)));
@@ -72,8 +72,8 @@ class SimpleRunner : public CalculatorRunner {
}
void CheckOutputTimestamps(
const std::vector<int64>& expected_frames,
const std::vector<int64>& expected_timestamps) const {
const std::vector<int64_t>& expected_frames,
const std::vector<int64_t>& expected_timestamps) const {
EXPECT_EQ(expected_frames.size(), Outputs().Index(0).packets.size());
EXPECT_EQ(expected_timestamps.size(), Outputs().Index(0).packets.size());
int count = 0;
@@ -112,7 +112,7 @@ MATCHER_P2(PacketAtTimestamp, payload, timestamp,
*result_listener << "at incorrect timestamp = " << arg.Timestamp().Value();
return false;
}
int64 actual_payload = arg.template Get<int64>();
int64_t actual_payload = arg.template Get<int64_t>();
if (actual_payload != payload) {
*result_listener << "with incorrect payload = " << actual_payload;
return false;
@@ -137,18 +137,18 @@ class ReproducibleJitterWithReflectionStrategyForTesting
//
// An EXPECT will fail if sequence is less than the number requested during
// processing.
static std::vector<uint64> random_sequence;
static std::vector<uint64_t> random_sequence;
protected:
virtual uint64 GetNextRandom(uint64 n) {
virtual uint64_t GetNextRandom(uint64_t n) {
EXPECT_LT(sequence_index_, random_sequence.size());
return random_sequence[sequence_index_++] % n;
}
private:
int32 sequence_index_ = 0;
int32_t sequence_index_ = 0;
};
std::vector<uint64>
std::vector<uint64_t>
ReproducibleJitterWithReflectionStrategyForTesting::random_sequence;
// PacketResamplerCalculator child class which injects a specified stream
@@ -469,7 +469,7 @@ TEST(PacketResamplerCalculatorTest, SetVideoHeader) {
}
)pb"));
for (const int64 ts : {0, 5000, 10010, 15001, 19990}) {
for (const int64_t ts : {0, 5000, 10010, 15001, 19990}) {
runner.MutableInputs()->Tag(kDataTag).packets.push_back(
Adopt(new std::string(absl::StrCat("Frame #", ts))).At(Timestamp(ts)));
}
@@ -123,7 +123,10 @@ class PreviousLoopbackCalculator : public Node {
// However, LOOP packet is empty.
kPrevLoop(cc).SetNextTimestampBound(main_spec.timestamp + 1);
} else {
kPrevLoop(cc).Send(loop_candidate.At(main_spec.timestamp));
// Avoids sending leftovers to a stream that's already closed.
if (!kPrevLoop(cc).IsClosed()) {
kPrevLoop(cc).Send(loop_candidate.At(main_spec.timestamp));
}
}
loop_packets_.pop_front();
main_packet_specs_.pop_front();
@@ -43,8 +43,8 @@ constexpr char kDisallowTag[] = "DISALLOW";
// Returns the timestamp values for a vector of Packets.
// TODO: puth this kind of test util in a common place.
std::vector<int64> TimestampValues(const std::vector<Packet>& packets) {
std::vector<int64> result;
std::vector<int64_t> TimestampValues(const std::vector<Packet>& packets) {
std::vector<int64_t> result;
for (const Packet& packet : packets) {
result.push_back(packet.Timestamp().Value());
}
@@ -371,7 +371,7 @@ TEST(PreviousLoopbackCalculator, EmptyLoopForever) {
for (int main_ts = 0; main_ts < 50; ++main_ts) {
send_packet("in", main_ts);
MP_EXPECT_OK(graph_.WaitUntilIdle());
std::vector<int64> ts_values = TimestampValues(outputs);
std::vector<int64_t> ts_values = TimestampValues(outputs);
EXPECT_EQ(ts_values.size(), main_ts + 1);
for (int j = 0; j < main_ts + 1; ++j) {
EXPECT_EQ(ts_values[j], j);
@@ -121,7 +121,7 @@ absl::Status SidePacketToStreamCalculator::GetContract(CalculatorContract* cc) {
if (cc->Outputs().HasTag(kTagAtTimestamp)) {
RET_CHECK_EQ(num_entries + 1, cc->InputSidePackets().NumEntries())
<< "For AT_TIMESTAMP tag, 2 input side packets are required.";
cc->InputSidePackets().Tag(kTagSideInputTimestamp).Set<int64>();
cc->InputSidePackets().Tag(kTagSideInputTimestamp).Set<int64_t>();
} else {
RET_CHECK_EQ(num_entries, cc->InputSidePackets().NumEntries())
<< "Same number of input side packets and output streams is required.";
@@ -178,8 +178,8 @@ absl::Status SidePacketToStreamCalculator::Close(CalculatorContext* cc) {
.AddPacket(cc->InputSidePackets().Index(i).At(timestamp));
}
} else if (cc->Outputs().HasTag(kTagAtTimestamp)) {
int64 timestamp =
cc->InputSidePackets().Tag(kTagSideInputTimestamp).Get<int64>();
int64_t timestamp =
cc->InputSidePackets().Tag(kTagSideInputTimestamp).Get<int64_t>();
for (int i = 0; i < cc->Outputs().NumEntries(output_tag_); ++i) {
cc->Outputs()
.Get(output_tag_, i)
@@ -18,6 +18,7 @@
#include "mediapipe/framework/formats/classification.pb.h"
#include "mediapipe/framework/formats/detection.pb.h"
#include "mediapipe/framework/formats/image.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/matrix.h"
#include "mediapipe/framework/formats/rect.pb.h"
@@ -86,4 +87,12 @@ REGISTER_CALCULATOR(SplitUint64tVectorCalculator);
typedef SplitVectorCalculator<float, false> SplitFloatVectorCalculator;
REGISTER_CALCULATOR(SplitFloatVectorCalculator);
typedef SplitVectorCalculator<mediapipe::Image, false>
SplitImageVectorCalculator;
REGISTER_CALCULATOR(SplitImageVectorCalculator);
typedef SplitVectorCalculator<std::array<float, 16>, false>
SplitAffineMatrixVectorCalculator;
REGISTER_CALCULATOR(SplitAffineMatrixVectorCalculator);
} // namespace mediapipe
@@ -12,11 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/port/status.h"
#include "mediapipe/framework/timestamp.h"
namespace mediapipe {
namespace api2 {
// A calculator that takes a packet of an input stream and converts it to an
// output side packet. This calculator only works under the assumption that the
@@ -28,21 +30,21 @@ namespace mediapipe {
// input_stream: "stream"
// output_side_packet: "side_packet"
// }
class StreamToSidePacketCalculator : public mediapipe::CalculatorBase {
class StreamToSidePacketCalculator : public Node {
public:
static absl::Status GetContract(mediapipe::CalculatorContract* cc) {
cc->Inputs().Index(0).SetAny();
cc->OutputSidePackets().Index(0).SetAny();
return absl::OkStatus();
}
static constexpr Input<AnyType>::Optional kIn{""};
static constexpr SideOutput<SameType<kIn>> kOut{""};
MEDIAPIPE_NODE_CONTRACT(kIn, kOut);
absl::Status Process(mediapipe::CalculatorContext* cc) override {
mediapipe::Packet& packet = cc->Inputs().Index(0).Value();
cc->OutputSidePackets().Index(0).Set(
packet.At(mediapipe::Timestamp::Unset()));
kOut(cc).Set(
kIn(cc).packet().As<AnyType>().At(mediapipe::Timestamp::Unset()));
return absl::OkStatus();
}
};
REGISTER_CALCULATOR(StreamToSidePacketCalculator);
MEDIAPIPE_REGISTER_NODE(StreamToSidePacketCalculator);
} // namespace api2
} // namespace mediapipe
+6 -2
View File
@@ -135,7 +135,6 @@ cc_library(
deps = [
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework/formats:image_frame_opencv",
"//mediapipe/framework/port:opencv_imgcodecs",
"//mediapipe/framework/port:opencv_imgproc",
"//mediapipe/framework/port:status",
],
@@ -317,6 +316,7 @@ cc_library(
cc_test(
name = "image_cropping_calculator_test",
srcs = ["image_cropping_calculator_test.cc"],
tags = ["not_run:arm"],
deps = [
":image_cropping_calculator",
":image_cropping_calculator_cc_proto",
@@ -650,6 +650,7 @@ cc_library(
cc_test(
name = "segmentation_smoothing_calculator_test",
srcs = ["segmentation_smoothing_calculator_test.cc"],
tags = ["not_run:arm"],
deps = [
":image_clone_calculator",
":image_clone_calculator_cc_proto",
@@ -771,7 +772,10 @@ cc_test(
"//mediapipe/calculators/tensor:testdata/image_to_tensor/medium_sub_rect_with_rotation_border_zero_interp_cubic.png",
"//mediapipe/calculators/tensor:testdata/image_to_tensor/noop_except_range.png",
],
tags = ["desktop_only_test"],
tags = [
"desktop_only_test",
"not_run:arm",
],
deps = [
":affine_transformation",
":image_transformation_calculator",
@@ -112,7 +112,7 @@ class BilateralFilterCalculator : public CalculatorBase {
REGISTER_CALCULATOR(BilateralFilterCalculator);
absl::Status BilateralFilterCalculator::GetContract(CalculatorContract* cc) {
CHECK_GE(cc->Inputs().NumEntries(), 1);
RET_CHECK_GE(cc->Inputs().NumEntries(), 1);
if (cc->Inputs().HasTag(kInputFrameTag) &&
cc->Inputs().HasTag(kInputFrameTagGpu)) {
@@ -110,7 +110,7 @@ REGISTER_CALCULATOR(SegmentationSmoothingCalculator);
absl::Status SegmentationSmoothingCalculator::GetContract(
CalculatorContract* cc) {
CHECK_GE(cc->Inputs().NumEntries(), 1);
RET_CHECK_GE(cc->Inputs().NumEntries(), 1);
cc->Inputs().Tag(kCurrentMaskTag).Set<Image>();
cc->Inputs().Tag(kPreviousMaskTag).Set<Image>();
@@ -142,7 +142,7 @@ class SetAlphaCalculator : public CalculatorBase {
REGISTER_CALCULATOR(SetAlphaCalculator);
absl::Status SetAlphaCalculator::GetContract(CalculatorContract* cc) {
CHECK_GE(cc->Inputs().NumEntries(), 1);
RET_CHECK_GE(cc->Inputs().NumEntries(), 1);
bool use_gpu = false;
@@ -38,7 +38,7 @@ std::string FourCCToString(libyuv::FourCC fourcc) {
buf[0] = (fourcc >> 24) & 0xff;
buf[1] = (fourcc >> 16) & 0xff;
buf[2] = (fourcc >> 8) & 0xff;
buf[3] = (fourcc)&0xff;
buf[3] = (fourcc) & 0xff;
buf[4] = 0;
return std::string(buf);
}
+7 -3
View File
@@ -228,7 +228,6 @@ cc_library(
"//mediapipe/tasks/metadata:metadata_schema_cc",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
],
alwayslink = 1,
@@ -280,7 +279,6 @@ cc_library(
"//mediapipe/tasks/cc/text/tokenizers:tokenizer_utils",
"//mediapipe/tasks/metadata:metadata_schema_cc",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
],
alwayslink = 1,
)
@@ -394,7 +392,7 @@ mediapipe_proto_library(
# If you want to have precise control of which implementations to include (e.g. for strict binary
# size concerns), depend on those implementations directly, and do not depend on
# :inference_calculator.
# In all cases, use "InferenceCalulator" in your graphs.
# In all cases, use "InferenceCalculator" in your graphs.
cc_library_with_tflite(
name = "inference_calculator_interface",
srcs = ["inference_calculator.cc"],
@@ -655,6 +653,11 @@ cc_library(
] + select({
"//mediapipe/gpu:disable_gpu": [],
"//conditions:default": ["tensor_converter_calculator_gpu_deps"],
}) + select({
"//mediapipe:apple": [
"//third_party/apple_frameworks:MetalKit",
],
"//conditions:default": [],
}),
alwayslink = 1,
)
@@ -1052,6 +1055,7 @@ cc_test(
"testdata/image_to_tensor/medium_sub_rect_with_rotation_border_zero.png",
"testdata/image_to_tensor/noop_except_range.png",
],
tags = ["not_run:arm"],
deps = [
":image_to_tensor_calculator",
":image_to_tensor_converter",
@@ -282,18 +282,23 @@ absl::Status AudioToTensorCalculator::Open(CalculatorContext* cc) {
if (options.has_volume_gain_db()) {
gain_ = pow(10, options.volume_gain_db() / 20.0);
}
RET_CHECK(kAudioSampleRateIn(cc).IsConnected() ^
!kAudioIn(cc).Header().IsEmpty())
<< "Must either specify the time series header of the \"AUDIO\" stream "
"or have the \"SAMPLE_RATE\" stream connected.";
if (!kAudioIn(cc).Header().IsEmpty()) {
mediapipe::TimeSeriesHeader input_header;
MP_RETURN_IF_ERROR(mediapipe::time_series_util::FillTimeSeriesHeaderIfValid(
kAudioIn(cc).Header(), &input_header));
if (stream_mode_) {
MP_RETURN_IF_ERROR(SetupStreamingResampler(input_header.sample_rate()));
} else {
source_sample_rate_ = input_header.sample_rate();
if (options.has_source_sample_rate()) {
source_sample_rate_ = options.source_sample_rate();
} else {
RET_CHECK(kAudioSampleRateIn(cc).IsConnected() ^
!kAudioIn(cc).Header().IsEmpty())
<< "Must either specify the time series header of the \"AUDIO\" stream "
"or have the \"SAMPLE_RATE\" stream connected.";
if (!kAudioIn(cc).Header().IsEmpty()) {
mediapipe::TimeSeriesHeader input_header;
MP_RETURN_IF_ERROR(
mediapipe::time_series_util::FillTimeSeriesHeaderIfValid(
kAudioIn(cc).Header(), &input_header));
if (stream_mode_) {
MP_RETURN_IF_ERROR(SetupStreamingResampler(input_header.sample_rate()));
} else {
source_sample_rate_ = input_header.sample_rate();
}
}
}
AppendZerosToSampleBuffer(padding_samples_before_);
@@ -85,4 +85,7 @@ message AudioToTensorCalculatorOptions {
// The volume gain, measured in dB.
// Scale the input audio amplitude by 10^(volume_gain_db/20).
optional double volume_gain_db = 12;
// The source number of samples per second (hertz) of the input audio buffers.
optional double source_sample_rate = 13;
}
@@ -22,7 +22,6 @@
#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/ascii.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
@@ -244,7 +243,8 @@ std::vector<Tensor> BertPreprocessorCalculator::GenerateInputTensors(
input_tensors.reserve(kNumInputTensorsForBert);
for (int i = 0; i < kNumInputTensorsForBert; ++i) {
input_tensors.push_back(
{Tensor::ElementType::kInt32, Tensor::Shape({tensor_size})});
{Tensor::ElementType::kInt32,
Tensor::Shape({1, tensor_size}, has_dynamic_input_tensors_)});
}
std::memcpy(input_tensors[input_ids_tensor_index_]
.GetCpuWriteView()
@@ -1,4 +1,4 @@
/* Copyright 2022 The MediaPipe Authors. All Rights Reserved.
/* Copyright 2022 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.
@@ -95,7 +95,8 @@ absl::Status FrameBufferProcessor::Convert(const mediapipe::Image& input,
static_cast<int>(range_max) == 255);
}
auto input_frame = input.GetGpuBuffer().GetReadView<FrameBuffer>();
auto input_frame =
input.GetGpuBuffer(/*upload_to_gpu=*/false).GetReadView<FrameBuffer>();
const auto& output_shape = output_tensor.shape();
MP_RETURN_IF_ERROR(ValidateTensorShape(output_shape));
FrameBuffer::Dimension output_dimension{/*width=*/output_shape.dims[2],
@@ -69,6 +69,7 @@ class InferenceCalculatorGlAdvancedImpl
gpu_delegate_options);
absl::Status ReadGpuCaches(tflite::gpu::TFLiteGPURunner* gpu_runner) const;
absl::Status SaveGpuCaches(tflite::gpu::TFLiteGPURunner* gpu_runner) const;
bool UseSerializedModel() const { return use_serialized_model_; }
private:
bool use_kernel_caching_ = false;
@@ -150,8 +151,6 @@ InferenceCalculatorGlAdvancedImpl::GpuInferenceRunner::Process(
}
absl::Status InferenceCalculatorGlAdvancedImpl::GpuInferenceRunner::Close() {
MP_RETURN_IF_ERROR(
on_disk_cache_helper_.SaveGpuCaches(tflite_gpu_runner_.get()));
return gpu_helper_.RunInGlContext([this]() -> absl::Status {
tflite_gpu_runner_.reset();
return absl::OkStatus();
@@ -226,9 +225,14 @@ InferenceCalculatorGlAdvancedImpl::GpuInferenceRunner::InitTFLiteGPURunner(
tflite_gpu_runner_->GetOutputShapes()[i].c};
}
if (on_disk_cache_helper_.UseSerializedModel()) {
tflite_gpu_runner_->ForceOpenCLInitFromSerializedModel();
}
MP_RETURN_IF_ERROR(
on_disk_cache_helper_.ReadGpuCaches(tflite_gpu_runner_.get()));
return tflite_gpu_runner_->Build();
MP_RETURN_IF_ERROR(tflite_gpu_runner_->Build());
return on_disk_cache_helper_.SaveGpuCaches(tflite_gpu_runner_.get());
}
#if defined(MEDIAPIPE_ANDROID) || defined(MEDIAPIPE_CHROMIUMOS)
@@ -96,6 +96,19 @@ absl::StatusOr<std::vector<Tensor>> InferenceInterpreterDelegateRunner::Run(
CalculatorContext* cc, const std::vector<Tensor>& input_tensors) {
// Read CPU input into tensors.
RET_CHECK_EQ(interpreter_->inputs().size(), input_tensors.size());
// If the input tensors have dynamic shape, then the tensors need to be
// resized and reallocated before we can copy the tensor values.
bool resized_tensor_shapes = false;
for (int i = 0; i < input_tensors.size(); ++i) {
if (input_tensors[i].shape().is_dynamic) {
interpreter_->ResizeInputTensorStrict(i, input_tensors[i].shape().dims);
resized_tensor_shapes = true;
}
}
// Reallocation is needed for memory sanity.
if (resized_tensor_shapes) interpreter_->AllocateTensors();
for (int i = 0; i < input_tensors.size(); ++i) {
const TfLiteType input_tensor_type =
interpreter_->tensor(interpreter_->inputs()[i])->type;
@@ -20,7 +20,6 @@
#include <vector>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "mediapipe/calculators/tensor/regex_preprocessor_calculator.pb.h"
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/api2/port.h"
@@ -161,7 +160,7 @@ absl::Status RegexPreprocessorCalculator::Process(CalculatorContext* cc) {
// not found in the tokenizer vocab.
std::vector<Tensor> result;
result.push_back(
{Tensor::ElementType::kInt32, Tensor::Shape({max_seq_len_})});
{Tensor::ElementType::kInt32, Tensor::Shape({1, max_seq_len_})});
std::memcpy(result[0].GetCpuWriteView().buffer<int32_t>(),
input_tokens.data(), input_tokens.size() * sizeof(int32_t));
kTensorsOut(cc).Send(std::move(result));
@@ -1,4 +1,4 @@
/* Copyright 2022 The MediaPipe Authors. All Rights Reserved.
/* Copyright 2022 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.
@@ -256,6 +256,7 @@ class TensorsToDetectionsCalculator : public Node {
bool gpu_inited_ = false;
bool gpu_input_ = false;
bool gpu_has_enough_work_groups_ = true;
bool anchors_init_ = false;
};
MEDIAPIPE_REGISTER_NODE(TensorsToDetectionsCalculator);
@@ -291,7 +292,7 @@ absl::Status TensorsToDetectionsCalculator::Open(CalculatorContext* cc) {
absl::Status TensorsToDetectionsCalculator::Process(CalculatorContext* cc) {
auto output_detections = absl::make_unique<std::vector<Detection>>();
bool gpu_processing = false;
if (CanUseGpu()) {
if (CanUseGpu() && gpu_has_enough_work_groups_) {
// Use GPU processing only if at least one input tensor is already on GPU
// (to avoid CPU->GPU overhead).
for (const auto& tensor : *kInTensors(cc)) {
@@ -321,11 +322,20 @@ absl::Status TensorsToDetectionsCalculator::Process(CalculatorContext* cc) {
RET_CHECK(!has_custom_box_indices_);
}
if (gpu_processing) {
if (!gpu_inited_) {
MP_RETURN_IF_ERROR(GpuInit(cc));
if (gpu_processing && !gpu_inited_) {
auto status = GpuInit(cc);
if (status.ok()) {
gpu_inited_ = true;
} else if (status.code() == absl::StatusCode::kFailedPrecondition) {
// For initialization error because of hardware limitation, fallback to
// CPU processing.
LOG(WARNING) << status.message();
} else {
// For other error, let the error propagates.
return status;
}
}
if (gpu_processing && gpu_inited_) {
MP_RETURN_IF_ERROR(ProcessGPU(cc, output_detections.get()));
} else {
MP_RETURN_IF_ERROR(ProcessCPU(cc, output_detections.get()));
@@ -346,17 +356,41 @@ absl::Status TensorsToDetectionsCalculator::ProcessCPU(
// TODO: Add flexible input tensor size handling.
auto raw_box_tensor =
&input_tensors[tensor_mapping_.detections_tensor_index()];
RET_CHECK_EQ(raw_box_tensor->shape().dims.size(), 3);
RET_CHECK_EQ(raw_box_tensor->shape().dims[0], 1);
RET_CHECK_GT(num_boxes_, 0) << "Please set num_boxes in calculator options";
RET_CHECK_EQ(raw_box_tensor->shape().dims[1], num_boxes_);
RET_CHECK_EQ(raw_box_tensor->shape().dims[2], num_coords_);
if (raw_box_tensor->shape().dims.size() == 3) {
// The tensors from CPU inference has dim 3.
RET_CHECK_EQ(raw_box_tensor->shape().dims[0], 1);
RET_CHECK_EQ(raw_box_tensor->shape().dims[1], num_boxes_);
RET_CHECK_EQ(raw_box_tensor->shape().dims[2], num_coords_);
} else if (raw_box_tensor->shape().dims.size() == 4) {
// The tensors from GPU inference has dim 4. For gpu-cpu fallback support,
// we allow tensors with 4 dims.
RET_CHECK_EQ(raw_box_tensor->shape().dims[0], 1);
RET_CHECK_EQ(raw_box_tensor->shape().dims[1], 1);
RET_CHECK_EQ(raw_box_tensor->shape().dims[2], num_boxes_);
RET_CHECK_EQ(raw_box_tensor->shape().dims[3], num_coords_);
} else {
return absl::InvalidArgumentError(
"The dimensions of box Tensor must be 3 or 4.");
}
auto raw_score_tensor =
&input_tensors[tensor_mapping_.scores_tensor_index()];
RET_CHECK_EQ(raw_score_tensor->shape().dims.size(), 3);
RET_CHECK_EQ(raw_score_tensor->shape().dims[0], 1);
RET_CHECK_EQ(raw_score_tensor->shape().dims[1], num_boxes_);
RET_CHECK_EQ(raw_score_tensor->shape().dims[2], num_classes_);
if (raw_score_tensor->shape().dims.size() == 3) {
// The tensors from CPU inference has dim 3.
RET_CHECK_EQ(raw_score_tensor->shape().dims[0], 1);
RET_CHECK_EQ(raw_score_tensor->shape().dims[1], num_boxes_);
RET_CHECK_EQ(raw_score_tensor->shape().dims[2], num_classes_);
} else if (raw_score_tensor->shape().dims.size() == 4) {
// The tensors from GPU inference has dim 4. For gpu-cpu fallback support,
// we allow tensors with 4 dims.
RET_CHECK_EQ(raw_score_tensor->shape().dims[0], 1);
RET_CHECK_EQ(raw_score_tensor->shape().dims[1], 1);
RET_CHECK_EQ(raw_score_tensor->shape().dims[2], num_boxes_);
RET_CHECK_EQ(raw_score_tensor->shape().dims[3], num_classes_);
} else {
return absl::InvalidArgumentError(
"The dimensions of score Tensor must be 3 or 4.");
}
auto raw_box_view = raw_box_tensor->GetCpuReadView();
auto raw_boxes = raw_box_view.buffer<float>();
auto raw_scores_view = raw_score_tensor->GetCpuReadView();
@@ -1111,8 +1145,13 @@ void main() {
int max_wg_size; // typically <= 1024
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1,
&max_wg_size); // y-dim
CHECK_LT(num_classes_, max_wg_size)
<< "# classes must be < " << max_wg_size;
gpu_has_enough_work_groups_ = num_classes_ < max_wg_size;
if (!gpu_has_enough_work_groups_) {
return absl::FailedPreconditionError(absl::StrFormat(
"Hardware limitation: Processing will be done on CPU, because "
"num_classes %d exceeds the max work_group size %d.",
num_classes_, max_wg_size));
}
// TODO support better filtering.
if (class_index_set_.is_allowlist) {
CHECK_EQ(class_index_set_.values.size(),
@@ -1370,7 +1409,13 @@ kernel void scoreKernel(
Tensor::ElementType::kFloat32, Tensor::Shape{1, num_boxes_ * 2});
// # filter classes supported is hardware dependent.
int max_wg_size = score_program_.maxTotalThreadsPerThreadgroup;
CHECK_LT(num_classes_, max_wg_size) << "# classes must be <" << max_wg_size;
gpu_has_enough_work_groups_ = num_classes_ < max_wg_size;
if (!gpu_has_enough_work_groups_) {
return absl::FailedPreconditionError(absl::StrFormat(
"Hardware limitation: Processing will be done on CPU, because "
"num_classes %d exceeds the max work_group size %d.",
num_classes_, max_wg_size));
}
}
#endif // !defined(MEDIAPIPE_DISABLE_GL_COMPUTE)
+34 -1
View File
@@ -400,6 +400,21 @@ cc_library(
# compile your binary with the flag TENSORFLOW_PROTOS=lite.
cc_library(
name = "tensorflow_inference_calculator_no_envelope_loader",
deps = [
":tensorflow_inference_calculator_for_boq",
],
alwayslink = 1,
)
# This dependency removed the following 3 targets because they failed Boq conformance test:
#
# tensorflow_jellyfish_deps
# jfprof_lib
# xprofilez_with_server
#
# If you need them plz consider tensorflow_inference_calculator_no_envelope_loader.
cc_library(
name = "tensorflow_inference_calculator_for_boq",
srcs = ["tensorflow_inference_calculator.cc"],
deps = [
":tensorflow_inference_calculator_cc_proto",
@@ -585,6 +600,24 @@ cc_library(
# See yaqs/1092546221614039040
cc_library(
name = "tensorflow_session_from_saved_model_generator_no_envelope_loader",
defines = select({
"//mediapipe:android": ["__ANDROID__"],
"//conditions:default": [],
}),
deps = [
":tensorflow_session_from_saved_model_generator_for_boq",
] + select({
"//conditions:default": [
"//learning/brain/frameworks/uptc/public:uptc_session_no_envelope_loader",
],
}),
alwayslink = 1,
)
# Same library as tensorflow_session_from_saved_model_generator without uptc_session,
# envelop_loader and remote_session dependencies.
cc_library(
name = "tensorflow_session_from_saved_model_generator_for_boq",
srcs = ["tensorflow_session_from_saved_model_generator.cc"],
defines = select({
"//mediapipe:android": ["__ANDROID__"],
@@ -899,7 +932,6 @@ cc_test(
"//mediapipe/framework:timestamp",
"//mediapipe/framework/formats:detection_cc_proto",
"//mediapipe/framework/formats:image_frame",
"//mediapipe/framework/formats:image_frame_opencv",
"//mediapipe/framework/formats:location",
"//mediapipe/framework/formats:location_opencv",
"//mediapipe/framework/port:gtest_main",
@@ -1049,6 +1081,7 @@ cc_test(
linkstatic = 1,
deps = [
":tensor_to_image_frame_calculator",
":tensor_to_image_frame_calculator_cc_proto",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:calculator_runner",
"//mediapipe/framework/formats:image_frame",
@@ -164,8 +164,8 @@ class PackMediaSequenceCalculator : public CalculatorBase {
}
}
CHECK(cc->Outputs().HasTag(kSequenceExampleTag) ||
cc->OutputSidePackets().HasTag(kSequenceExampleTag))
RET_CHECK(cc->Outputs().HasTag(kSequenceExampleTag) ||
cc->OutputSidePackets().HasTag(kSequenceExampleTag))
<< "Neither the output stream nor the output side packet is set to "
"output the sequence example.";
if (cc->Outputs().HasTag(kSequenceExampleTag)) {
@@ -23,7 +23,6 @@
#include "mediapipe/framework/calculator_runner.h"
#include "mediapipe/framework/formats/detection.pb.h"
#include "mediapipe/framework/formats/image_frame.h"
#include "mediapipe/framework/formats/image_frame_opencv.h"
#include "mediapipe/framework/formats/location.h"
#include "mediapipe/framework/formats/location_opencv.h"
#include "mediapipe/framework/port/gmock.h"
@@ -96,7 +95,8 @@ TEST_F(PackMediaSequenceCalculatorTest, PacksTwoImages) {
mpms::SetClipMediaId(test_video_id, input_sequence.get());
cv::Mat image(2, 3, CV_8UC3, cv::Scalar(0, 0, 255));
std::vector<uchar> bytes;
ASSERT_TRUE(cv::imencode(".jpg", image, bytes, {80}));
ASSERT_TRUE(
cv::imencode(".jpg", image, bytes, {cv::IMWRITE_HDR_COMPRESSION, 1}));
OpenCvImageEncoderCalculatorResults encoded_image;
encoded_image.set_encoded_image(bytes.data(), bytes.size());
encoded_image.set_width(2);
@@ -139,7 +139,8 @@ TEST_F(PackMediaSequenceCalculatorTest, PacksTwoPrefixedImages) {
mpms::SetClipMediaId(test_video_id, input_sequence.get());
cv::Mat image(2, 3, CV_8UC3, cv::Scalar(0, 0, 255));
std::vector<uchar> bytes;
ASSERT_TRUE(cv::imencode(".jpg", image, bytes, {80}));
ASSERT_TRUE(
cv::imencode(".jpg", image, bytes, {cv::IMWRITE_HDR_COMPRESSION, 1}));
OpenCvImageEncoderCalculatorResults encoded_image;
encoded_image.set_encoded_image(bytes.data(), bytes.size());
encoded_image.set_width(2);
@@ -378,7 +379,8 @@ TEST_F(PackMediaSequenceCalculatorTest, PacksAdditionalContext) {
Adopt(input_sequence.release());
cv::Mat image(2, 3, CV_8UC3, cv::Scalar(0, 0, 255));
std::vector<uchar> bytes;
ASSERT_TRUE(cv::imencode(".jpg", image, bytes, {80}));
ASSERT_TRUE(
cv::imencode(".jpg", image, bytes, {cv::IMWRITE_HDR_COMPRESSION, 1}));
OpenCvImageEncoderCalculatorResults encoded_image;
encoded_image.set_encoded_image(bytes.data(), bytes.size());
auto image_ptr =
@@ -410,7 +412,8 @@ TEST_F(PackMediaSequenceCalculatorTest, PacksTwoForwardFlowEncodeds) {
cv::Mat image(2, 3, CV_8UC3, cv::Scalar(0, 0, 255));
std::vector<uchar> bytes;
ASSERT_TRUE(cv::imencode(".jpg", image, bytes, {80}));
ASSERT_TRUE(
cv::imencode(".jpg", image, bytes, {cv::IMWRITE_HDR_COMPRESSION, 1}));
std::string test_flow_string(bytes.begin(), bytes.end());
OpenCvImageEncoderCalculatorResults encoded_flow;
encoded_flow.set_encoded_image(test_flow_string);
@@ -618,7 +621,8 @@ TEST_F(PackMediaSequenceCalculatorTest, PacksBBoxWithImages) {
}
cv::Mat image(height, width, CV_8UC3, cv::Scalar(0, 0, 255));
std::vector<uchar> bytes;
ASSERT_TRUE(cv::imencode(".jpg", image, bytes, {80}));
ASSERT_TRUE(
cv::imencode(".jpg", image, bytes, {cv::IMWRITE_HDR_COMPRESSION, 1}));
OpenCvImageEncoderCalculatorResults encoded_image;
encoded_image.set_encoded_image(bytes.data(), bytes.size());
encoded_image.set_width(width);
@@ -767,7 +771,8 @@ TEST_F(PackMediaSequenceCalculatorTest, MissingStreamOK) {
cv::Mat image(2, 3, CV_8UC3, cv::Scalar(0, 0, 255));
std::vector<uchar> bytes;
ASSERT_TRUE(cv::imencode(".jpg", image, bytes, {80}));
ASSERT_TRUE(
cv::imencode(".jpg", image, bytes, {cv::IMWRITE_HDR_COMPRESSION, 1}));
std::string test_flow_string(bytes.begin(), bytes.end());
OpenCvImageEncoderCalculatorResults encoded_flow;
encoded_flow.set_encoded_image(test_flow_string);
@@ -813,7 +818,8 @@ TEST_F(PackMediaSequenceCalculatorTest, MissingStreamNotOK) {
mpms::SetClipMediaId(test_video_id, input_sequence.get());
cv::Mat image(2, 3, CV_8UC3, cv::Scalar(0, 0, 255));
std::vector<uchar> bytes;
ASSERT_TRUE(cv::imencode(".jpg", image, bytes, {80}));
ASSERT_TRUE(
cv::imencode(".jpg", image, bytes, {cv::IMWRITE_HDR_COMPRESSION, 1}));
std::string test_flow_string(bytes.begin(), bytes.end());
OpenCvImageEncoderCalculatorResults encoded_flow;
encoded_flow.set_encoded_image(test_flow_string);
@@ -970,7 +976,8 @@ TEST_F(PackMediaSequenceCalculatorTest, TestReconcilingAnnotations) {
auto input_sequence = ::absl::make_unique<tf::SequenceExample>();
cv::Mat image(2, 3, CV_8UC3, cv::Scalar(0, 0, 255));
std::vector<uchar> bytes;
ASSERT_TRUE(cv::imencode(".jpg", image, bytes, {80}));
ASSERT_TRUE(
cv::imencode(".jpg", image, bytes, {cv::IMWRITE_HDR_COMPRESSION, 1}));
OpenCvImageEncoderCalculatorResults encoded_image;
encoded_image.set_encoded_image(bytes.data(), bytes.size());
encoded_image.set_width(2);
@@ -1021,7 +1028,8 @@ TEST_F(PackMediaSequenceCalculatorTest, TestOverwritingAndReconciling) {
auto input_sequence = ::absl::make_unique<tf::SequenceExample>();
cv::Mat image(2, 3, CV_8UC3, cv::Scalar(0, 0, 255));
std::vector<uchar> bytes;
ASSERT_TRUE(cv::imencode(".jpg", image, bytes, {80}));
ASSERT_TRUE(
cv::imencode(".jpg", image, bytes, {cv::IMWRITE_HDR_COMPRESSION, 1}));
OpenCvImageEncoderCalculatorResults encoded_image;
encoded_image.set_encoded_image(bytes.data(), bytes.size());
int height = 2;
@@ -65,6 +65,7 @@ class TensorToImageFrameCalculator : public CalculatorBase {
private:
float scale_factor_;
bool scale_per_frame_min_max_;
};
REGISTER_CALCULATOR(TensorToImageFrameCalculator);
@@ -88,6 +89,8 @@ absl::Status TensorToImageFrameCalculator::GetContract(CalculatorContract* cc) {
absl::Status TensorToImageFrameCalculator::Open(CalculatorContext* cc) {
scale_factor_ =
cc->Options<TensorToImageFrameCalculatorOptions>().scale_factor();
scale_per_frame_min_max_ = cc->Options<TensorToImageFrameCalculatorOptions>()
.scale_per_frame_min_max();
cc->SetOffset(TimestampDiff(0));
return absl::OkStatus();
}
@@ -109,16 +112,38 @@ absl::Status TensorToImageFrameCalculator::Process(CalculatorContext* cc) {
auto format = (depth == 3 ? ImageFormat::SRGB : ImageFormat::GRAY8);
const int32_t total_size = height * width * depth;
if (scale_per_frame_min_max_) {
RET_CHECK_EQ(input_tensor.dtype(), tensorflow::DT_FLOAT)
<< "Setting scale_per_frame_min_max requires FLOAT input tensors.";
}
::std::unique_ptr<const ImageFrame> output;
if (input_tensor.dtype() == tensorflow::DT_FLOAT) {
// Allocate buffer with alignments.
std::unique_ptr<uint8_t[]> buffer(
new (std::align_val_t(EIGEN_MAX_ALIGN_BYTES)) uint8_t[total_size]);
auto data = input_tensor.flat<float>().data();
float min = 1e23;
float max = -1e23;
if (scale_per_frame_min_max_) {
for (int i = 0; i < total_size; ++i) {
float d = scale_factor_ * data[i];
if (d < min) {
min = d;
}
if (d > max) {
max = d;
}
}
}
for (int i = 0; i < total_size; ++i) {
float d = scale_factor_ * data[i];
if (d < 0) d = 0;
if (d > 255) d = 255;
float d = data[i];
if (scale_per_frame_min_max_) {
d = 255 * (d - min) / (max - min + 1e-9);
} else {
d = scale_factor_ * d;
if (d < 0) d = 0;
if (d > 255) d = 255;
}
buffer[i] = d;
}
output = ::absl::make_unique<ImageFrame>(
@@ -26,4 +26,8 @@ message TensorToImageFrameCalculatorOptions {
// Multiples floating point tensor outputs by this value before converting to
// uint8. This is useful for converting from range [0, 1] to [0, 255]
optional float scale_factor = 1 [default = 1.0];
// If true, scales any FLOAT tensor input of [min, max] to be between [0, 255]
// per frame. This overrides any explicit scale_factor.
optional bool scale_per_frame_min_max = 2 [default = false];
}
@@ -11,7 +11,9 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <type_traits>
#include "mediapipe/calculators/tensorflow/tensor_to_image_frame_calculator.pb.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/calculator_runner.h"
#include "mediapipe/framework/formats/image_frame.h"
@@ -32,11 +34,14 @@ constexpr char kImage[] = "IMAGE";
template <class TypeParam>
class TensorToImageFrameCalculatorTest : public ::testing::Test {
protected:
void SetUpRunner() {
void SetUpRunner(bool scale_per_frame_min_max = false) {
CalculatorGraphConfig::Node config;
config.set_calculator("TensorToImageFrameCalculator");
config.add_input_stream("TENSOR:input_tensor");
config.add_output_stream("IMAGE:output_image");
config.mutable_options()
->MutableExtension(mediapipe::TensorToImageFrameCalculatorOptions::ext)
->set_scale_per_frame_min_max(scale_per_frame_min_max);
runner_ = absl::make_unique<CalculatorRunner>(config);
}
@@ -157,4 +162,47 @@ TYPED_TEST(TensorToImageFrameCalculatorTest,
}
}
TYPED_TEST(TensorToImageFrameCalculatorTest,
Converts3DTensorToImageFrame2DGrayWithScaling) {
this->SetUpRunner(true);
auto& runner = this->runner_;
constexpr int kWidth = 16;
constexpr int kHeight = 8;
const tf::TensorShape tensor_shape{kHeight, kWidth};
auto tensor = absl::make_unique<tf::Tensor>(
tf::DataTypeToEnum<TypeParam>::v(), tensor_shape);
auto tensor_vec = tensor->template flat<TypeParam>().data();
// Writing sequence of integers as floats which we want normalized.
tensor_vec[0] = 255;
for (int i = 1; i < kWidth * kHeight; ++i) {
tensor_vec[i] = 200;
}
const int64_t time = 1234;
runner->MutableInputs()->Tag(kTensor).packets.push_back(
Adopt(tensor.release()).At(Timestamp(time)));
if (!std::is_same<TypeParam, float>::value) {
EXPECT_FALSE(runner->Run().ok());
return; // Short circuit because does not apply to other types.
} else {
EXPECT_TRUE(runner->Run().ok());
const std::vector<Packet>& output_packets =
runner->Outputs().Tag(kImage).packets;
EXPECT_EQ(1, output_packets.size());
EXPECT_EQ(time, output_packets[0].Timestamp().Value());
const ImageFrame& output_image = output_packets[0].Get<ImageFrame>();
EXPECT_EQ(ImageFormat::GRAY8, output_image.Format());
EXPECT_EQ(kWidth, output_image.Width());
EXPECT_EQ(kHeight, output_image.Height());
EXPECT_EQ(255, output_image.PixelData()[0]);
for (int i = 1; i < kWidth * kHeight; ++i) {
const uint8_t pixel_value = output_image.PixelData()[i];
ASSERT_EQ(0, pixel_value);
}
}
}
} // namespace mediapipe
@@ -61,12 +61,12 @@ constexpr char kSessionBundleTag[] = "SESSION_BUNDLE";
// overload GPU/TPU/...
class SimpleSemaphore {
public:
explicit SimpleSemaphore(uint32 initial_count) : count_(initial_count) {}
explicit SimpleSemaphore(uint32_t initial_count) : count_(initial_count) {}
SimpleSemaphore(const SimpleSemaphore&) = delete;
SimpleSemaphore(SimpleSemaphore&&) = delete;
// Acquires the semaphore by certain amount.
void Acquire(uint32 amount) {
void Acquire(uint32_t amount) {
mutex_.Lock();
while (count_ < amount) {
cond_.Wait(&mutex_);
@@ -76,7 +76,7 @@ class SimpleSemaphore {
}
// Releases the semaphore by certain amount.
void Release(uint32 amount) {
void Release(uint32_t amount) {
mutex_.Lock();
count_ += amount;
cond_.SignalAll();
@@ -84,7 +84,7 @@ class SimpleSemaphore {
}
private:
uint32 count_;
uint32_t count_;
absl::Mutex mutex_;
absl::CondVar cond_;
};
@@ -488,7 +488,7 @@ class TensorFlowInferenceCalculator : public CalculatorBase {
// necessary.
absl::Status OutputBatch(CalculatorContext* cc,
std::unique_ptr<InferenceState> inference_state) {
const int64 start_time = absl::ToUnixMicros(clock_->TimeNow());
const int64_t start_time = absl::ToUnixMicros(clock_->TimeNow());
std::vector<std::pair<mediapipe::ProtoString, tf::Tensor>> input_tensors;
for (auto& keyed_tensors : inference_state->input_tensor_batches_) {
@@ -544,7 +544,7 @@ class TensorFlowInferenceCalculator : public CalculatorBase {
get_session_run_throttle(options_.max_concurrent_session_runs());
session_run_throttle->Acquire(1);
}
const int64 run_start_time = absl::ToUnixMicros(clock_->TimeNow());
const int64_t run_start_time = absl::ToUnixMicros(clock_->TimeNow());
tf::Status tf_status;
{
#if !defined(MEDIAPIPE_MOBILE) && !defined(__APPLE__)
@@ -562,7 +562,7 @@ class TensorFlowInferenceCalculator : public CalculatorBase {
// informative error message.
RET_CHECK(tf_status.ok()) << "Run failed: " << tf_status.ToString();
const int64 run_end_time = absl::ToUnixMicros(clock_->TimeNow());
const int64_t run_end_time = absl::ToUnixMicros(clock_->TimeNow());
cc->GetCounter(kTotalSessionRunsTimeUsecsCounterSuffix)
->IncrementBy(run_end_time - run_start_time);
cc->GetCounter(kTotalNumSessionRunsCounterSuffix)->Increment();
@@ -611,7 +611,7 @@ class TensorFlowInferenceCalculator : public CalculatorBase {
}
// Get end time and report.
const int64 end_time = absl::ToUnixMicros(clock_->TimeNow());
const int64_t end_time = absl::ToUnixMicros(clock_->TimeNow());
cc->GetCounter(kTotalUsecsCounterSuffix)
->IncrementBy(end_time - start_time);
cc->GetCounter(kTotalProcessedTimestampsCounterSuffix)
@@ -650,7 +650,7 @@ class TensorFlowInferenceCalculator : public CalculatorBase {
// The static singleton semaphore to throttle concurrent session runs.
static SimpleSemaphore* get_session_run_throttle(
int32 max_concurrent_session_runs) {
int32_t max_concurrent_session_runs) {
static SimpleSemaphore* session_run_throttle =
new SimpleSemaphore(max_concurrent_session_runs);
return session_run_throttle;
@@ -197,15 +197,15 @@ class UnpackMediaSequenceCalculator : public CalculatorBase {
// timestamp and the associated feature. This information is used in process
// to output batches of packets in order.
timestamps_.clear();
int64 last_timestamp_seen = Timestamp::PreStream().Value();
int64_t last_timestamp_seen = Timestamp::PreStream().Value();
first_timestamp_seen_ = Timestamp::OneOverPostStream().Value();
for (const auto& map_kv : sequence_->feature_lists().feature_list()) {
if (absl::StrContains(map_kv.first, "/timestamp")) {
LOG(INFO) << "Found feature timestamps: " << map_kv.first
<< " with size: " << map_kv.second.feature_size();
int64 recent_timestamp = Timestamp::PreStream().Value();
int64_t recent_timestamp = Timestamp::PreStream().Value();
for (int i = 0; i < map_kv.second.feature_size(); ++i) {
int64 next_timestamp =
int64_t next_timestamp =
mpms::GetInt64sAt(*sequence_, map_kv.first, i).Get(0);
RET_CHECK_GT(next_timestamp, recent_timestamp)
<< "Timestamps must be sequential. If you're seeing this message "
@@ -361,8 +361,8 @@ class UnpackMediaSequenceCalculator : public CalculatorBase {
// any particular call to Process(). At the every end, we output the
// poststream packets. If we only have poststream packets,
// last_timestamp_key_ will be empty.
int64 start_timestamp = 0;
int64 end_timestamp = 0;
int64_t start_timestamp = 0;
int64_t end_timestamp = 0;
if (last_timestamp_key_.empty() || process_poststream_) {
process_poststream_ = true;
start_timestamp = Timestamp::PostStream().Value();
@@ -481,14 +481,14 @@ class UnpackMediaSequenceCalculator : public CalculatorBase {
// Store a map from the keys for each stream to the timestamps for each
// key. This allows us to identify which packets to output for each stream
// for timestamps within a given time window.
std::map<std::string, std::vector<int64>> timestamps_;
std::map<std::string, std::vector<int64_t>> timestamps_;
// Store the stream with the latest timestamp in the SequenceExample.
std::string last_timestamp_key_;
// Store the index of the current timestamp. Will be less than
// timestamps_[last_timestamp_key_].size().
int current_timestamp_index_;
// Store the very first timestamp, so we output everything on the first frame.
int64 first_timestamp_seen_;
int64_t first_timestamp_seen_;
// List of keypoint names.
std::vector<std::string> keypoint_names_;
// Default keypoint location when missing.
@@ -54,7 +54,7 @@ class VectorToTensorFloatCalculatorTest : public ::testing::Test {
}
}
const int64 time = 1234;
const int64_t time = 1234;
runner_->MutableInputs()->Index(0).packets.push_back(
Adopt(input.release()).At(Timestamp(time)));
@@ -91,7 +91,7 @@ TEST_F(VectorToTensorFloatCalculatorTest, ConvertsFromVectorFloat) {
// 2^i can be represented exactly in floating point numbers if 'i' is small.
input->at(i) = static_cast<float>(1 << i);
}
const int64 time = 1234;
const int64_t time = 1234;
runner_->MutableInputs()->Index(0).packets.push_back(
Adopt(input.release()).At(Timestamp(time)));
+64 -1
View File
@@ -899,16 +899,77 @@ mediapipe_proto_library(
cc_library(
name = "landmarks_smoothing_calculator",
srcs = ["landmarks_smoothing_calculator.cc"],
hdrs = ["landmarks_smoothing_calculator.h"],
deps = [
":landmarks_smoothing_calculator_cc_proto",
":landmarks_smoothing_calculator_utils",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:timestamp",
"//mediapipe/framework/api2:node",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:rect_cc_proto",
"//mediapipe/framework/port:ret_check",
],
alwayslink = 1,
)
cc_library(
name = "landmarks_smoothing_calculator_utils",
srcs = ["landmarks_smoothing_calculator_utils.cc"],
hdrs = ["landmarks_smoothing_calculator_utils.h"],
deps = [
":landmarks_smoothing_calculator_cc_proto",
"//mediapipe/framework:calculator_context",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:rect_cc_proto",
"//mediapipe/framework/port:ret_check",
"//mediapipe/util/filtering:one_euro_filter",
"//mediapipe/util/filtering:relative_velocity_filter",
"@com_google_absl//absl/algorithm:container",
],
alwayslink = 1,
)
cc_test(
name = "landmarks_smoothing_calculator_utils_test",
size = "small",
srcs = ["landmarks_smoothing_calculator_utils_test.cc"],
deps = [
":landmarks_smoothing_calculator_utils",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/port:gtest_main",
],
)
cc_library(
name = "multi_landmarks_smoothing_calculator",
srcs = ["multi_landmarks_smoothing_calculator.cc"],
hdrs = ["multi_landmarks_smoothing_calculator.h"],
deps = [
":landmarks_smoothing_calculator_cc_proto",
":landmarks_smoothing_calculator_utils",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:timestamp",
"//mediapipe/framework/api2:node",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:rect_cc_proto",
"//mediapipe/framework/port:ret_check",
],
alwayslink = 1,
)
cc_library(
name = "multi_world_landmarks_smoothing_calculator",
srcs = ["multi_world_landmarks_smoothing_calculator.cc"],
hdrs = ["multi_world_landmarks_smoothing_calculator.h"],
deps = [
":landmarks_smoothing_calculator_cc_proto",
":landmarks_smoothing_calculator_utils",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework:timestamp",
"//mediapipe/framework/api2:node",
"//mediapipe/framework/formats:landmark_cc_proto",
"//mediapipe/framework/formats:rect_cc_proto",
"//mediapipe/framework/port:ret_check",
],
alwayslink = 1,
)
@@ -1285,12 +1346,14 @@ cc_library(
srcs = ["flat_color_image_calculator.cc"],
deps = [
":flat_color_image_calculator_cc_proto",
"//mediapipe/framework:calculator_contract",
"//mediapipe/framework:calculator_framework",
"//mediapipe/framework/api2:node",
"//mediapipe/framework/formats:image",
"//mediapipe/framework/formats:image_frame",
"//mediapipe/framework/formats:image_frame_opencv",
"//mediapipe/framework/port:opencv_core",
"//mediapipe/framework/port:ret_check",
"//mediapipe/util:color_cc_proto",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
@@ -172,7 +172,7 @@ class AnnotationOverlayCalculator : public CalculatorBase {
REGISTER_CALCULATOR(AnnotationOverlayCalculator);
absl::Status AnnotationOverlayCalculator::GetContract(CalculatorContract* cc) {
CHECK_GE(cc->Inputs().NumEntries(), 1);
RET_CHECK_GE(cc->Inputs().NumEntries(), 1);
bool use_gpu = false;
@@ -189,13 +189,13 @@ absl::Status AnnotationOverlayCalculator::GetContract(CalculatorContract* cc) {
#if !MEDIAPIPE_DISABLE_GPU
if (cc->Inputs().HasTag(kGpuBufferTag)) {
cc->Inputs().Tag(kGpuBufferTag).Set<mediapipe::GpuBuffer>();
CHECK(cc->Outputs().HasTag(kGpuBufferTag));
RET_CHECK(cc->Outputs().HasTag(kGpuBufferTag));
use_gpu = true;
}
#endif // !MEDIAPIPE_DISABLE_GPU
if (cc->Inputs().HasTag(kImageFrameTag)) {
cc->Inputs().Tag(kImageFrameTag).Set<ImageFrame>();
CHECK(cc->Outputs().HasTag(kImageFrameTag));
RET_CHECK(cc->Outputs().HasTag(kImageFrameTag));
}
// Data streams to render.
@@ -471,7 +471,7 @@ absl::Status AnnotationOverlayCalculator::CreateRenderTargetCpu(
auto input_mat = formats::MatView(&input_frame);
if (input_frame.Format() == ImageFormat::GRAY8) {
cv::Mat rgb_mat;
cv::cvtColor(input_mat, rgb_mat, CV_GRAY2RGB);
cv::cvtColor(input_mat, rgb_mat, cv::COLOR_GRAY2RGB);
rgb_mat.copyTo(*image_mat);
} else {
input_mat.copyTo(*image_mat);
@@ -1,4 +1,4 @@
/* Copyright 2022 The MediaPipe Authors. All Rights Reserved.
/* Copyright 2022 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.
@@ -15,14 +15,13 @@
#include <memory>
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "mediapipe/calculators/util/flat_color_image_calculator.pb.h"
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/calculator_contract.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/formats/image.h"
#include "mediapipe/framework/formats/image_frame.h"
#include "mediapipe/framework/formats/image_frame_opencv.h"
#include "mediapipe/framework/port/opencv_core_inc.h"
#include "mediapipe/util/color.pb.h"
namespace mediapipe {
@@ -32,6 +31,7 @@ namespace {
using ::mediapipe::api2::Input;
using ::mediapipe::api2::Node;
using ::mediapipe::api2::Output;
using ::mediapipe::api2::SideOutput;
} // namespace
// A calculator for generating an image filled with a single color.
@@ -45,7 +45,8 @@ using ::mediapipe::api2::Output;
//
// Outputs:
// IMAGE (Image)
// Image filled with the requested color.
// Image filled with the requested color. Can be either an output_stream
// or an output_side_packet.
//
// Example useage:
// node {
@@ -68,9 +69,10 @@ class FlatColorImageCalculator : public Node {
public:
static constexpr Input<Image>::Optional kInImage{"IMAGE"};
static constexpr Input<Color>::Optional kInColor{"COLOR"};
static constexpr Output<Image> kOutImage{"IMAGE"};
static constexpr Output<Image>::Optional kOutImage{"IMAGE"};
static constexpr SideOutput<Image>::Optional kOutSideImage{"IMAGE"};
MEDIAPIPE_NODE_CONTRACT(kInImage, kInColor, kOutImage);
MEDIAPIPE_NODE_CONTRACT(kInImage, kInColor, kOutImage, kOutSideImage);
static absl::Status UpdateContract(CalculatorContract* cc) {
const auto& options = cc->Options<FlatColorImageCalculatorOptions>();
@@ -81,6 +83,13 @@ class FlatColorImageCalculator : public Node {
RET_CHECK(kInColor(cc).IsConnected() ^ options.has_color())
<< "Either set COLOR input stream, or set through options";
RET_CHECK(kOutImage(cc).IsConnected() ^ kOutSideImage(cc).IsConnected())
<< "Set IMAGE either as output stream, or as output side packet";
RET_CHECK(!kOutSideImage(cc).IsConnected() ||
(options.has_output_height() && options.has_output_width()))
<< "Set size through options, when setting IMAGE as output side packet";
return absl::OkStatus();
}
@@ -88,6 +97,9 @@ class FlatColorImageCalculator : public Node {
absl::Status Process(CalculatorContext* cc) override;
private:
std::optional<std::shared_ptr<ImageFrame>> CreateOutputFrame(
CalculatorContext* cc);
bool use_dimension_from_option_ = false;
bool use_color_from_option_ = false;
};
@@ -96,10 +108,31 @@ MEDIAPIPE_REGISTER_NODE(FlatColorImageCalculator);
absl::Status FlatColorImageCalculator::Open(CalculatorContext* cc) {
use_dimension_from_option_ = !kInImage(cc).IsConnected();
use_color_from_option_ = !kInColor(cc).IsConnected();
if (!kOutImage(cc).IsConnected()) {
std::optional<std::shared_ptr<ImageFrame>> output_frame =
CreateOutputFrame(cc);
if (output_frame.has_value()) {
kOutSideImage(cc).Set(Image(output_frame.value()));
}
}
return absl::OkStatus();
}
absl::Status FlatColorImageCalculator::Process(CalculatorContext* cc) {
if (kOutImage(cc).IsConnected()) {
std::optional<std::shared_ptr<ImageFrame>> output_frame =
CreateOutputFrame(cc);
if (output_frame.has_value()) {
kOutImage(cc).Send(Image(output_frame.value()));
}
}
return absl::OkStatus();
}
std::optional<std::shared_ptr<ImageFrame>>
FlatColorImageCalculator::CreateOutputFrame(CalculatorContext* cc) {
const auto& options = cc->Options<FlatColorImageCalculatorOptions>();
int output_height = -1;
@@ -112,7 +145,7 @@ absl::Status FlatColorImageCalculator::Process(CalculatorContext* cc) {
output_height = input_image.height();
output_width = input_image.width();
} else {
return absl::OkStatus();
return std::nullopt;
}
Color color;
@@ -121,7 +154,7 @@ absl::Status FlatColorImageCalculator::Process(CalculatorContext* cc) {
} else if (!kInColor(cc).IsEmpty()) {
color = kInColor(cc).Get();
} else {
return absl::OkStatus();
return std::nullopt;
}
auto output_frame = std::make_shared<ImageFrame>(ImageFormat::SRGB,
@@ -130,9 +163,7 @@ absl::Status FlatColorImageCalculator::Process(CalculatorContext* cc) {
output_mat.setTo(cv::Scalar(color.r(), color.g(), color.b()));
kOutImage(cc).Send(Image(output_frame));
return absl::OkStatus();
return output_frame;
}
} // namespace mediapipe
@@ -113,6 +113,35 @@ TEST(FlatColorImageCalculatorTest, SpecifyDimensionThroughOptions) {
}
}
TEST(FlatColorImageCalculatorTest, ProducesOutputSidePacket) {
CalculatorRunner runner(R"pb(
calculator: "FlatColorImageCalculator"
output_side_packet: "IMAGE:out_packet"
options {
[mediapipe.FlatColorImageCalculatorOptions.ext] {
output_width: 1
output_height: 1
color: {
r: 100,
g: 200,
b: 255,
}
}
}
)pb");
MP_ASSERT_OK(runner.Run());
const auto& image = runner.OutputSidePackets().Tag(kImageTag).Get<Image>();
EXPECT_EQ(image.width(), 1);
EXPECT_EQ(image.height(), 1);
auto image_frame = image.GetImageFrameSharedPtr();
const uint8_t* pixel_data = image_frame->PixelData();
EXPECT_EQ(pixel_data[0], 100);
EXPECT_EQ(pixel_data[1], 200);
EXPECT_EQ(pixel_data[2], 255);
}
TEST(FlatColorImageCalculatorTest, FailureMissingDimension) {
CalculatorRunner runner(R"pb(
calculator: "FlatColorImageCalculator"
@@ -206,5 +235,56 @@ TEST(FlatColorImageCalculatorTest, FailureDuplicateColor) {
HasSubstr("Either set COLOR input stream"));
}
TEST(FlatColorImageCalculatorTest, FailureDuplicateOutputs) {
CalculatorRunner runner(R"pb(
calculator: "FlatColorImageCalculator"
output_stream: "IMAGE:out_image"
output_side_packet: "IMAGE:out_packet"
options {
[mediapipe.FlatColorImageCalculatorOptions.ext] {
output_width: 1
output_height: 1
color: {
r: 100,
g: 200,
b: 255,
}
}
}
)pb");
ASSERT_THAT(
runner.Run().message(),
HasSubstr("Set IMAGE either as output stream, or as output side packet"));
}
TEST(FlatColorImageCalculatorTest, FailureSettingInputImageOnOutputSidePacket) {
CalculatorRunner runner(R"pb(
calculator: "FlatColorImageCalculator"
input_stream: "IMAGE:image"
output_side_packet: "IMAGE:out_packet"
options {
[mediapipe.FlatColorImageCalculatorOptions.ext] {
color: {
r: 100,
g: 200,
b: 255,
}
}
}
)pb");
auto image_frame = std::make_shared<ImageFrame>(ImageFormat::SRGB,
kImageWidth, kImageHeight);
for (int ts = 0; ts < 3; ++ts) {
runner.MutableInputs()->Tag(kImageTag).packets.push_back(
MakePacket<Image>(image_frame).At(Timestamp(ts)));
}
ASSERT_THAT(runner.Run().message(),
HasSubstr("Set size through options, when setting IMAGE as "
"output side packet"));
}
} // namespace
} // namespace mediapipe
@@ -1,4 +1,4 @@
// Copyright 2020 The MediaPipe Authors.
// 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.
@@ -12,471 +12,105 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mediapipe/calculators/util/landmarks_smoothing_calculator.h"
#include <memory>
#include "absl/algorithm/container.h"
#include "mediapipe/calculators/util/landmarks_smoothing_calculator.pb.h"
#include "mediapipe/calculators/util/landmarks_smoothing_calculator_utils.h"
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/framework/timestamp.h"
#include "mediapipe/util/filtering/one_euro_filter.h"
#include "mediapipe/util/filtering/relative_velocity_filter.h"
namespace mediapipe {
namespace api2 {
namespace {
constexpr char kNormalizedLandmarksTag[] = "NORM_LANDMARKS";
constexpr char kLandmarksTag[] = "LANDMARKS";
constexpr char kImageSizeTag[] = "IMAGE_SIZE";
constexpr char kObjectScaleRoiTag[] = "OBJECT_SCALE_ROI";
constexpr char kNormalizedFilteredLandmarksTag[] = "NORM_FILTERED_LANDMARKS";
constexpr char kFilteredLandmarksTag[] = "FILTERED_LANDMARKS";
using ::mediapipe::NormalizedRect;
using mediapipe::OneEuroFilter;
using ::mediapipe::Rect;
using mediapipe::RelativeVelocityFilter;
void NormalizedLandmarksToLandmarks(
const NormalizedLandmarkList& norm_landmarks, const int image_width,
const int image_height, LandmarkList* landmarks) {
for (int i = 0; i < norm_landmarks.landmark_size(); ++i) {
const auto& norm_landmark = norm_landmarks.landmark(i);
auto* landmark = landmarks->add_landmark();
landmark->set_x(norm_landmark.x() * image_width);
landmark->set_y(norm_landmark.y() * image_height);
// Scale Z the same way as X (using image width).
landmark->set_z(norm_landmark.z() * image_width);
landmark->set_visibility(norm_landmark.visibility());
landmark->set_presence(norm_landmark.presence());
}
}
void LandmarksToNormalizedLandmarks(const LandmarkList& landmarks,
const int image_width,
const int image_height,
NormalizedLandmarkList* norm_landmarks) {
for (int i = 0; i < landmarks.landmark_size(); ++i) {
const auto& landmark = landmarks.landmark(i);
auto* norm_landmark = norm_landmarks->add_landmark();
norm_landmark->set_x(landmark.x() / image_width);
norm_landmark->set_y(landmark.y() / image_height);
// Scale Z the same way as X (using image width).
norm_landmark->set_z(landmark.z() / image_width);
norm_landmark->set_visibility(landmark.visibility());
norm_landmark->set_presence(landmark.presence());
}
}
// Estimate object scale to use its inverse value as velocity scale for
// RelativeVelocityFilter. If value will be too small (less than
// `options_.min_allowed_object_scale`) smoothing will be disabled and
// landmarks will be returned as is.
// Object scale is calculated as average between bounding box width and height
// with sides parallel to axis.
float GetObjectScale(const LandmarkList& landmarks) {
const auto& lm_minmax_x = absl::c_minmax_element(
landmarks.landmark(),
[](const auto& a, const auto& b) { return a.x() < b.x(); });
const float x_min = lm_minmax_x.first->x();
const float x_max = lm_minmax_x.second->x();
const auto& lm_minmax_y = absl::c_minmax_element(
landmarks.landmark(),
[](const auto& a, const auto& b) { return a.y() < b.y(); });
const float y_min = lm_minmax_y.first->y();
const float y_max = lm_minmax_y.second->y();
const float object_width = x_max - x_min;
const float object_height = y_max - y_min;
return (object_width + object_height) / 2.0f;
}
float GetObjectScale(const NormalizedRect& roi, const int image_width,
const int image_height) {
const float object_width = roi.width() * image_width;
const float object_height = roi.height() * image_height;
return (object_width + object_height) / 2.0f;
}
float GetObjectScale(const Rect& roi) {
return (roi.width() + roi.height()) / 2.0f;
}
// Abstract class for various landmarks filters.
class LandmarksFilter {
public:
virtual ~LandmarksFilter() = default;
virtual absl::Status Reset() { return absl::OkStatus(); }
virtual absl::Status Apply(const LandmarkList& in_landmarks,
const absl::Duration& timestamp,
const absl::optional<float> object_scale_opt,
LandmarkList* out_landmarks) = 0;
};
// Returns landmarks as is without smoothing.
class NoFilter : public LandmarksFilter {
public:
absl::Status Apply(const LandmarkList& in_landmarks,
const absl::Duration& timestamp,
const absl::optional<float> object_scale_opt,
LandmarkList* out_landmarks) override {
*out_landmarks = in_landmarks;
return absl::OkStatus();
}
};
// Please check RelativeVelocityFilter documentation for details.
class VelocityFilter : public LandmarksFilter {
public:
VelocityFilter(int window_size, float velocity_scale,
float min_allowed_object_scale, bool disable_value_scaling)
: window_size_(window_size),
velocity_scale_(velocity_scale),
min_allowed_object_scale_(min_allowed_object_scale),
disable_value_scaling_(disable_value_scaling) {}
absl::Status Reset() override {
x_filters_.clear();
y_filters_.clear();
z_filters_.clear();
return absl::OkStatus();
}
absl::Status Apply(const LandmarkList& in_landmarks,
const absl::Duration& timestamp,
const absl::optional<float> object_scale_opt,
LandmarkList* out_landmarks) override {
// Get value scale as inverse value of the object scale.
// If value is too small smoothing will be disabled and landmarks will be
// returned as is.
float value_scale = 1.0f;
if (!disable_value_scaling_) {
const float object_scale =
object_scale_opt ? *object_scale_opt : GetObjectScale(in_landmarks);
if (object_scale < min_allowed_object_scale_) {
*out_landmarks = in_landmarks;
return absl::OkStatus();
}
value_scale = 1.0f / object_scale;
}
// Initialize filters once.
MP_RETURN_IF_ERROR(InitializeFiltersIfEmpty(in_landmarks.landmark_size()));
// Filter landmarks. Every axis of every landmark is filtered separately.
for (int i = 0; i < in_landmarks.landmark_size(); ++i) {
const auto& in_landmark = in_landmarks.landmark(i);
auto* out_landmark = out_landmarks->add_landmark();
*out_landmark = in_landmark;
out_landmark->set_x(
x_filters_[i].Apply(timestamp, value_scale, in_landmark.x()));
out_landmark->set_y(
y_filters_[i].Apply(timestamp, value_scale, in_landmark.y()));
out_landmark->set_z(
z_filters_[i].Apply(timestamp, value_scale, in_landmark.z()));
}
return absl::OkStatus();
}
private:
// Initializes filters for the first time or after Reset. If initialized then
// check the size.
absl::Status InitializeFiltersIfEmpty(const int n_landmarks) {
if (!x_filters_.empty()) {
RET_CHECK_EQ(x_filters_.size(), n_landmarks);
RET_CHECK_EQ(y_filters_.size(), n_landmarks);
RET_CHECK_EQ(z_filters_.size(), n_landmarks);
return absl::OkStatus();
}
x_filters_.resize(n_landmarks,
RelativeVelocityFilter(window_size_, velocity_scale_));
y_filters_.resize(n_landmarks,
RelativeVelocityFilter(window_size_, velocity_scale_));
z_filters_.resize(n_landmarks,
RelativeVelocityFilter(window_size_, velocity_scale_));
return absl::OkStatus();
}
int window_size_;
float velocity_scale_;
float min_allowed_object_scale_;
bool disable_value_scaling_;
std::vector<RelativeVelocityFilter> x_filters_;
std::vector<RelativeVelocityFilter> y_filters_;
std::vector<RelativeVelocityFilter> z_filters_;
};
// Please check OneEuroFilter documentation for details.
class OneEuroFilterImpl : public LandmarksFilter {
public:
OneEuroFilterImpl(double frequency, double min_cutoff, double beta,
double derivate_cutoff, float min_allowed_object_scale,
bool disable_value_scaling)
: frequency_(frequency),
min_cutoff_(min_cutoff),
beta_(beta),
derivate_cutoff_(derivate_cutoff),
min_allowed_object_scale_(min_allowed_object_scale),
disable_value_scaling_(disable_value_scaling) {}
absl::Status Reset() override {
x_filters_.clear();
y_filters_.clear();
z_filters_.clear();
return absl::OkStatus();
}
absl::Status Apply(const LandmarkList& in_landmarks,
const absl::Duration& timestamp,
const absl::optional<float> object_scale_opt,
LandmarkList* out_landmarks) override {
// Initialize filters once.
MP_RETURN_IF_ERROR(InitializeFiltersIfEmpty(in_landmarks.landmark_size()));
// Get value scale as inverse value of the object scale.
// If value is too small smoothing will be disabled and landmarks will be
// returned as is.
float value_scale = 1.0f;
if (!disable_value_scaling_) {
const float object_scale =
object_scale_opt ? *object_scale_opt : GetObjectScale(in_landmarks);
if (object_scale < min_allowed_object_scale_) {
*out_landmarks = in_landmarks;
return absl::OkStatus();
}
value_scale = 1.0f / object_scale;
}
// Filter landmarks. Every axis of every landmark is filtered separately.
for (int i = 0; i < in_landmarks.landmark_size(); ++i) {
const auto& in_landmark = in_landmarks.landmark(i);
auto* out_landmark = out_landmarks->add_landmark();
*out_landmark = in_landmark;
out_landmark->set_x(
x_filters_[i].Apply(timestamp, value_scale, in_landmark.x()));
out_landmark->set_y(
y_filters_[i].Apply(timestamp, value_scale, in_landmark.y()));
out_landmark->set_z(
z_filters_[i].Apply(timestamp, value_scale, in_landmark.z()));
}
return absl::OkStatus();
}
private:
// Initializes filters for the first time or after Reset. If initialized then
// check the size.
absl::Status InitializeFiltersIfEmpty(const int n_landmarks) {
if (!x_filters_.empty()) {
RET_CHECK_EQ(x_filters_.size(), n_landmarks);
RET_CHECK_EQ(y_filters_.size(), n_landmarks);
RET_CHECK_EQ(z_filters_.size(), n_landmarks);
return absl::OkStatus();
}
for (int i = 0; i < n_landmarks; ++i) {
x_filters_.push_back(
OneEuroFilter(frequency_, min_cutoff_, beta_, derivate_cutoff_));
y_filters_.push_back(
OneEuroFilter(frequency_, min_cutoff_, beta_, derivate_cutoff_));
z_filters_.push_back(
OneEuroFilter(frequency_, min_cutoff_, beta_, derivate_cutoff_));
}
return absl::OkStatus();
}
double frequency_;
double min_cutoff_;
double beta_;
double derivate_cutoff_;
double min_allowed_object_scale_;
bool disable_value_scaling_;
std::vector<OneEuroFilter> x_filters_;
std::vector<OneEuroFilter> y_filters_;
std::vector<OneEuroFilter> z_filters_;
};
using ::mediapipe::landmarks_smoothing::GetObjectScale;
using ::mediapipe::landmarks_smoothing::InitializeLandmarksFilter;
using ::mediapipe::landmarks_smoothing::LandmarksFilter;
using ::mediapipe::landmarks_smoothing::LandmarksToNormalizedLandmarks;
using ::mediapipe::landmarks_smoothing::NormalizedLandmarksToLandmarks;
} // namespace
// A calculator to smooth landmarks over time.
//
// Inputs:
// NORM_LANDMARKS: A NormalizedLandmarkList of landmarks you want to smooth.
// IMAGE_SIZE: A std::pair<int, int> represention of image width and height.
// Required to perform all computations in absolute coordinates to avoid any
// influence of normalized values.
// OBJECT_SCALE_ROI (optional): A NormRect or Rect (depending on the format of
// input landmarks) used to determine the object scale for some of the
// filters. If not provided - object scale will be calculated from
// landmarks.
//
// Outputs:
// NORM_FILTERED_LANDMARKS: A NormalizedLandmarkList of smoothed landmarks.
//
// Example config:
// node {
// calculator: "LandmarksSmoothingCalculator"
// input_stream: "NORM_LANDMARKS:pose_landmarks"
// input_stream: "IMAGE_SIZE:image_size"
// input_stream: "OBJECT_SCALE_ROI:roi"
// output_stream: "NORM_FILTERED_LANDMARKS:pose_landmarks_filtered"
// options: {
// [mediapipe.LandmarksSmoothingCalculatorOptions.ext] {
// velocity_filter: {
// window_size: 5
// velocity_scale: 10.0
// }
// }
// }
// }
//
class LandmarksSmoothingCalculator : public CalculatorBase {
class LandmarksSmoothingCalculatorImpl
: public NodeImpl<LandmarksSmoothingCalculator> {
public:
static absl::Status GetContract(CalculatorContract* cc);
absl::Status Open(CalculatorContext* cc) override;
absl::Status Process(CalculatorContext* cc) override;
absl::Status Open(CalculatorContext* cc) override {
ASSIGN_OR_RETURN(landmarks_filter_,
InitializeLandmarksFilter(
cc->Options<LandmarksSmoothingCalculatorOptions>()));
return absl::OkStatus();
}
absl::Status Process(CalculatorContext* cc) override {
// Check that landmarks are not empty and reset the filter if so.
// Don't emit an empty packet for this timestamp.
if ((kInNormLandmarks(cc).IsConnected() &&
kInNormLandmarks(cc).IsEmpty()) ||
(kInLandmarks(cc).IsConnected() && kInLandmarks(cc).IsEmpty())) {
MP_RETURN_IF_ERROR(landmarks_filter_->Reset());
return absl::OkStatus();
}
const auto& timestamp =
absl::Microseconds(cc->InputTimestamp().Microseconds());
if (kInNormLandmarks(cc).IsConnected()) {
const auto& in_norm_landmarks = kInNormLandmarks(cc).Get();
int image_width;
int image_height;
std::tie(image_width, image_height) = kImageSize(cc).Get();
absl::optional<float> object_scale;
if (kObjectScaleRoi(cc).IsConnected() && !kObjectScaleRoi(cc).IsEmpty()) {
auto& roi = kObjectScaleRoi(cc).Get<NormalizedRect>();
object_scale = GetObjectScale(roi, image_width, image_height);
}
auto in_landmarks = absl::make_unique<LandmarkList>();
NormalizedLandmarksToLandmarks(in_norm_landmarks, image_width,
image_height, *in_landmarks.get());
auto out_landmarks = absl::make_unique<LandmarkList>();
MP_RETURN_IF_ERROR(landmarks_filter_->Apply(
*in_landmarks, timestamp, object_scale, *out_landmarks));
auto out_norm_landmarks = absl::make_unique<NormalizedLandmarkList>();
LandmarksToNormalizedLandmarks(*out_landmarks, image_width, image_height,
*out_norm_landmarks.get());
kOutNormLandmarks(cc).Send(std::move(out_norm_landmarks));
} else {
const auto& in_landmarks = kInLandmarks(cc).Get();
absl::optional<float> object_scale;
if (kObjectScaleRoi(cc).IsConnected() && !kObjectScaleRoi(cc).IsEmpty()) {
auto& roi = kObjectScaleRoi(cc).Get<Rect>();
object_scale = GetObjectScale(roi);
}
auto out_landmarks = absl::make_unique<LandmarkList>();
MP_RETURN_IF_ERROR(landmarks_filter_->Apply(
in_landmarks, timestamp, object_scale, *out_landmarks));
kOutLandmarks(cc).Send(std::move(out_landmarks));
}
return absl::OkStatus();
}
private:
std::unique_ptr<LandmarksFilter> landmarks_filter_;
};
REGISTER_CALCULATOR(LandmarksSmoothingCalculator);
absl::Status LandmarksSmoothingCalculator::GetContract(CalculatorContract* cc) {
if (cc->Inputs().HasTag(kNormalizedLandmarksTag)) {
cc->Inputs().Tag(kNormalizedLandmarksTag).Set<NormalizedLandmarkList>();
cc->Inputs().Tag(kImageSizeTag).Set<std::pair<int, int>>();
cc->Outputs()
.Tag(kNormalizedFilteredLandmarksTag)
.Set<NormalizedLandmarkList>();
if (cc->Inputs().HasTag(kObjectScaleRoiTag)) {
cc->Inputs().Tag(kObjectScaleRoiTag).Set<NormalizedRect>();
}
} else {
cc->Inputs().Tag(kLandmarksTag).Set<LandmarkList>();
cc->Outputs().Tag(kFilteredLandmarksTag).Set<LandmarkList>();
if (cc->Inputs().HasTag(kObjectScaleRoiTag)) {
cc->Inputs().Tag(kObjectScaleRoiTag).Set<Rect>();
}
}
return absl::OkStatus();
}
absl::Status LandmarksSmoothingCalculator::Open(CalculatorContext* cc) {
cc->SetOffset(TimestampDiff(0));
// Pick landmarks filter.
const auto& options = cc->Options<LandmarksSmoothingCalculatorOptions>();
if (options.has_no_filter()) {
landmarks_filter_ = absl::make_unique<NoFilter>();
} else if (options.has_velocity_filter()) {
landmarks_filter_ = absl::make_unique<VelocityFilter>(
options.velocity_filter().window_size(),
options.velocity_filter().velocity_scale(),
options.velocity_filter().min_allowed_object_scale(),
options.velocity_filter().disable_value_scaling());
} else if (options.has_one_euro_filter()) {
landmarks_filter_ = absl::make_unique<OneEuroFilterImpl>(
options.one_euro_filter().frequency(),
options.one_euro_filter().min_cutoff(),
options.one_euro_filter().beta(),
options.one_euro_filter().derivate_cutoff(),
options.one_euro_filter().min_allowed_object_scale(),
options.one_euro_filter().disable_value_scaling());
} else {
RET_CHECK_FAIL()
<< "Landmarks filter is either not specified or not supported";
}
return absl::OkStatus();
}
absl::Status LandmarksSmoothingCalculator::Process(CalculatorContext* cc) {
// Check that landmarks are not empty and reset the filter if so.
// Don't emit an empty packet for this timestamp.
if ((cc->Inputs().HasTag(kNormalizedLandmarksTag) &&
cc->Inputs().Tag(kNormalizedLandmarksTag).IsEmpty()) ||
(cc->Inputs().HasTag(kLandmarksTag) &&
cc->Inputs().Tag(kLandmarksTag).IsEmpty())) {
MP_RETURN_IF_ERROR(landmarks_filter_->Reset());
return absl::OkStatus();
}
const auto& timestamp =
absl::Microseconds(cc->InputTimestamp().Microseconds());
if (cc->Inputs().HasTag(kNormalizedLandmarksTag)) {
const auto& in_norm_landmarks =
cc->Inputs().Tag(kNormalizedLandmarksTag).Get<NormalizedLandmarkList>();
int image_width;
int image_height;
std::tie(image_width, image_height) =
cc->Inputs().Tag(kImageSizeTag).Get<std::pair<int, int>>();
absl::optional<float> object_scale;
if (cc->Inputs().HasTag(kObjectScaleRoiTag) &&
!cc->Inputs().Tag(kObjectScaleRoiTag).IsEmpty()) {
auto& roi = cc->Inputs().Tag(kObjectScaleRoiTag).Get<NormalizedRect>();
object_scale = GetObjectScale(roi, image_width, image_height);
}
auto in_landmarks = absl::make_unique<LandmarkList>();
NormalizedLandmarksToLandmarks(in_norm_landmarks, image_width, image_height,
in_landmarks.get());
auto out_landmarks = absl::make_unique<LandmarkList>();
MP_RETURN_IF_ERROR(landmarks_filter_->Apply(
*in_landmarks, timestamp, object_scale, out_landmarks.get()));
auto out_norm_landmarks = absl::make_unique<NormalizedLandmarkList>();
LandmarksToNormalizedLandmarks(*out_landmarks, image_width, image_height,
out_norm_landmarks.get());
cc->Outputs()
.Tag(kNormalizedFilteredLandmarksTag)
.Add(out_norm_landmarks.release(), cc->InputTimestamp());
} else {
const auto& in_landmarks =
cc->Inputs().Tag(kLandmarksTag).Get<LandmarkList>();
absl::optional<float> object_scale;
if (cc->Inputs().HasTag(kObjectScaleRoiTag) &&
!cc->Inputs().Tag(kObjectScaleRoiTag).IsEmpty()) {
auto& roi = cc->Inputs().Tag(kObjectScaleRoiTag).Get<Rect>();
object_scale = GetObjectScale(roi);
}
auto out_landmarks = absl::make_unique<LandmarkList>();
MP_RETURN_IF_ERROR(landmarks_filter_->Apply(
in_landmarks, timestamp, object_scale, out_landmarks.get()));
cc->Outputs()
.Tag(kFilteredLandmarksTag)
.Add(out_landmarks.release(), cc->InputTimestamp());
}
return absl::OkStatus();
}
MEDIAPIPE_NODE_IMPLEMENTATION(LandmarksSmoothingCalculatorImpl);
} // namespace api2
} // namespace mediapipe
@@ -0,0 +1,106 @@
// 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.
#ifndef MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_SMOOTHING_CALCULATOR_H_
#define MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_SMOOTHING_CALCULATOR_H_
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
#include "mediapipe/framework/port/ret_check.h"
namespace mediapipe {
namespace api2 {
// A calculator to smooth landmarks over time.
//
// Inputs:
// NORM_LANDMARKS (optional): A NormalizedLandmarkList of landmarks you want
// to smooth.
// LANDMARKS (optional): A LandmarkList of landmarks you want to smooth.
// IMAGE_SIZE (optional): A std::pair<int, int> represention of image width
// and height. Required to perform all computations in absolute coordinates
// when smoothing NORM_LANDMARKS to avoid any influence of normalized
// values.
// OBJECT_SCALE_ROI (optional): A NormRect or Rect (depending on the format of
// input landmarks) used to determine the object scale for some of the
// filters. If not provided - object scale will be calculated from
// landmarks.
//
// Outputs:
// NORM_FILTERED_LANDMARKS (optional): A NormalizedLandmarkList of smoothed
// landmarks.
// FILTERED_LANDMARKS (optional): A LandmarkList of smoothed landmarks.
//
// Example config:
// node {
// calculator: "LandmarksSmoothingCalculator"
// input_stream: "NORM_LANDMARKS:landmarks"
// input_stream: "IMAGE_SIZE:image_size"
// input_stream: "OBJECT_SCALE_ROI:roi"
// output_stream: "NORM_FILTERED_LANDMARKS:landmarks_filtered"
// options: {
// [mediapipe.LandmarksSmoothingCalculatorOptions.ext] {
// velocity_filter: {
// window_size: 5
// velocity_scale: 10.0
// }
// }
// }
// }
//
class LandmarksSmoothingCalculator : public NodeIntf {
public:
static constexpr Input<mediapipe::NormalizedLandmarkList>::Optional
kInNormLandmarks{"NORM_LANDMARKS"};
static constexpr Input<mediapipe::LandmarkList>::Optional kInLandmarks{
"LANDMARKS"};
static constexpr Input<std::pair<int, int>>::Optional kImageSize{
"IMAGE_SIZE"};
static constexpr Input<OneOf<NormalizedRect, Rect>>::Optional kObjectScaleRoi{
"OBJECT_SCALE_ROI"};
static constexpr Output<mediapipe::NormalizedLandmarkList>::Optional
kOutNormLandmarks{"NORM_FILTERED_LANDMARKS"};
static constexpr Output<mediapipe::LandmarkList>::Optional kOutLandmarks{
"FILTERED_LANDMARKS"};
MEDIAPIPE_NODE_INTERFACE(LandmarksSmoothingCalculator, kInNormLandmarks,
kInLandmarks, kImageSize, kObjectScaleRoi,
kOutNormLandmarks, kOutLandmarks);
static absl::Status UpdateContract(CalculatorContract* cc) {
RET_CHECK(kInNormLandmarks(cc).IsConnected() ^
kInLandmarks(cc).IsConnected())
<< "One and only one of NORM_LANDMARKS and LANDMARKS input is allowed";
// TODO: Verify scale ROI is of the same type as landmarks
// that are being smoothed.
if (kInNormLandmarks(cc).IsConnected()) {
RET_CHECK(kImageSize(cc).IsConnected());
RET_CHECK(kOutNormLandmarks(cc).IsConnected());
RET_CHECK(!kOutLandmarks(cc).IsConnected());
} else {
RET_CHECK(!kImageSize(cc).IsConnected());
RET_CHECK(kOutLandmarks(cc).IsConnected());
RET_CHECK(!kOutNormLandmarks(cc).IsConnected());
}
return absl::OkStatus();
}
};
} // namespace api2
} // namespace mediapipe
#endif // MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_SMOOTHING_CALCULATOR_H_
@@ -0,0 +1,375 @@
// 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.
#include "mediapipe/calculators/util/landmarks_smoothing_calculator_utils.h"
#include <iostream>
#include "mediapipe/calculators/util/landmarks_smoothing_calculator.pb.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/util/filtering/one_euro_filter.h"
#include "mediapipe/util/filtering/relative_velocity_filter.h"
namespace mediapipe {
namespace landmarks_smoothing {
namespace {
using ::mediapipe::NormalizedRect;
using ::mediapipe::OneEuroFilter;
using ::mediapipe::Rect;
using ::mediapipe::RelativeVelocityFilter;
// Estimate object scale to use its inverse value as velocity scale for
// RelativeVelocityFilter. If value will be too small (less than
// `options_.min_allowed_object_scale`) smoothing will be disabled and
// landmarks will be returned as is.
// Object scale is calculated as average between bounding box width and height
// with sides parallel to axis.
float GetObjectScale(const LandmarkList& landmarks) {
const auto& lm_minmax_x = absl::c_minmax_element(
landmarks.landmark(),
[](const auto& a, const auto& b) { return a.x() < b.x(); });
const float x_min = lm_minmax_x.first->x();
const float x_max = lm_minmax_x.second->x();
const auto& lm_minmax_y = absl::c_minmax_element(
landmarks.landmark(),
[](const auto& a, const auto& b) { return a.y() < b.y(); });
const float y_min = lm_minmax_y.first->y();
const float y_max = lm_minmax_y.second->y();
const float object_width = x_max - x_min;
const float object_height = y_max - y_min;
return (object_width + object_height) / 2.0f;
}
// Returns landmarks as is without smoothing.
class NoFilter : public LandmarksFilter {
public:
absl::Status Apply(const LandmarkList& in_landmarks,
const absl::Duration& timestamp,
const absl::optional<float> object_scale_opt,
LandmarkList& out_landmarks) override {
out_landmarks = in_landmarks;
return absl::OkStatus();
}
};
// Please check RelativeVelocityFilter documentation for details.
class VelocityFilter : public LandmarksFilter {
public:
VelocityFilter(int window_size, float velocity_scale,
float min_allowed_object_scale, bool disable_value_scaling)
: window_size_(window_size),
velocity_scale_(velocity_scale),
min_allowed_object_scale_(min_allowed_object_scale),
disable_value_scaling_(disable_value_scaling) {}
absl::Status Reset() override {
x_filters_.clear();
y_filters_.clear();
z_filters_.clear();
return absl::OkStatus();
}
absl::Status Apply(const LandmarkList& in_landmarks,
const absl::Duration& timestamp,
const absl::optional<float> object_scale_opt,
LandmarkList& out_landmarks) override {
// Get value scale as inverse value of the object scale.
// If value is too small smoothing will be disabled and landmarks will be
// returned as is.
float value_scale = 1.0f;
if (!disable_value_scaling_) {
const float object_scale =
object_scale_opt ? *object_scale_opt : GetObjectScale(in_landmarks);
if (object_scale < min_allowed_object_scale_) {
out_landmarks = in_landmarks;
return absl::OkStatus();
}
value_scale = 1.0f / object_scale;
}
// Initialize filters once.
MP_RETURN_IF_ERROR(InitializeFiltersIfEmpty(in_landmarks.landmark_size()));
// Filter landmarks. Every axis of every landmark is filtered separately.
for (int i = 0; i < in_landmarks.landmark_size(); ++i) {
const auto& in_landmark = in_landmarks.landmark(i);
auto* out_landmark = out_landmarks.add_landmark();
*out_landmark = in_landmark;
out_landmark->set_x(
x_filters_[i].Apply(timestamp, value_scale, in_landmark.x()));
out_landmark->set_y(
y_filters_[i].Apply(timestamp, value_scale, in_landmark.y()));
out_landmark->set_z(
z_filters_[i].Apply(timestamp, value_scale, in_landmark.z()));
}
return absl::OkStatus();
}
private:
// Initializes filters for the first time or after Reset. If initialized then
// check the size.
absl::Status InitializeFiltersIfEmpty(const int n_landmarks) {
if (!x_filters_.empty()) {
RET_CHECK_EQ(x_filters_.size(), n_landmarks);
RET_CHECK_EQ(y_filters_.size(), n_landmarks);
RET_CHECK_EQ(z_filters_.size(), n_landmarks);
return absl::OkStatus();
}
x_filters_.resize(n_landmarks,
RelativeVelocityFilter(window_size_, velocity_scale_));
y_filters_.resize(n_landmarks,
RelativeVelocityFilter(window_size_, velocity_scale_));
z_filters_.resize(n_landmarks,
RelativeVelocityFilter(window_size_, velocity_scale_));
return absl::OkStatus();
}
int window_size_;
float velocity_scale_;
float min_allowed_object_scale_;
bool disable_value_scaling_;
std::vector<RelativeVelocityFilter> x_filters_;
std::vector<RelativeVelocityFilter> y_filters_;
std::vector<RelativeVelocityFilter> z_filters_;
};
// Please check OneEuroFilter documentation for details.
class OneEuroFilterImpl : public LandmarksFilter {
public:
OneEuroFilterImpl(double frequency, double min_cutoff, double beta,
double derivate_cutoff, float min_allowed_object_scale,
bool disable_value_scaling)
: frequency_(frequency),
min_cutoff_(min_cutoff),
beta_(beta),
derivate_cutoff_(derivate_cutoff),
min_allowed_object_scale_(min_allowed_object_scale),
disable_value_scaling_(disable_value_scaling) {}
absl::Status Reset() override {
x_filters_.clear();
y_filters_.clear();
z_filters_.clear();
return absl::OkStatus();
}
absl::Status Apply(const LandmarkList& in_landmarks,
const absl::Duration& timestamp,
const absl::optional<float> object_scale_opt,
LandmarkList& out_landmarks) override {
// Initialize filters once.
MP_RETURN_IF_ERROR(InitializeFiltersIfEmpty(in_landmarks.landmark_size()));
// Get value scale as inverse value of the object scale.
// If value is too small smoothing will be disabled and landmarks will be
// returned as is.
float value_scale = 1.0f;
if (!disable_value_scaling_) {
const float object_scale =
object_scale_opt ? *object_scale_opt : GetObjectScale(in_landmarks);
if (object_scale < min_allowed_object_scale_) {
out_landmarks = in_landmarks;
return absl::OkStatus();
}
value_scale = 1.0f / object_scale;
}
// Filter landmarks. Every axis of every landmark is filtered separately.
for (int i = 0; i < in_landmarks.landmark_size(); ++i) {
const auto& in_landmark = in_landmarks.landmark(i);
auto* out_landmark = out_landmarks.add_landmark();
*out_landmark = in_landmark;
out_landmark->set_x(
x_filters_[i].Apply(timestamp, value_scale, in_landmark.x()));
out_landmark->set_y(
y_filters_[i].Apply(timestamp, value_scale, in_landmark.y()));
out_landmark->set_z(
z_filters_[i].Apply(timestamp, value_scale, in_landmark.z()));
}
return absl::OkStatus();
}
private:
// Initializes filters for the first time or after Reset. If initialized then
// check the size.
absl::Status InitializeFiltersIfEmpty(const int n_landmarks) {
if (!x_filters_.empty()) {
RET_CHECK_EQ(x_filters_.size(), n_landmarks);
RET_CHECK_EQ(y_filters_.size(), n_landmarks);
RET_CHECK_EQ(z_filters_.size(), n_landmarks);
return absl::OkStatus();
}
for (int i = 0; i < n_landmarks; ++i) {
x_filters_.push_back(
OneEuroFilter(frequency_, min_cutoff_, beta_, derivate_cutoff_));
y_filters_.push_back(
OneEuroFilter(frequency_, min_cutoff_, beta_, derivate_cutoff_));
z_filters_.push_back(
OneEuroFilter(frequency_, min_cutoff_, beta_, derivate_cutoff_));
}
return absl::OkStatus();
}
double frequency_;
double min_cutoff_;
double beta_;
double derivate_cutoff_;
double min_allowed_object_scale_;
bool disable_value_scaling_;
std::vector<OneEuroFilter> x_filters_;
std::vector<OneEuroFilter> y_filters_;
std::vector<OneEuroFilter> z_filters_;
};
} // namespace
void NormalizedLandmarksToLandmarks(
const NormalizedLandmarkList& norm_landmarks, const int image_width,
const int image_height, LandmarkList& landmarks) {
for (int i = 0; i < norm_landmarks.landmark_size(); ++i) {
const auto& norm_landmark = norm_landmarks.landmark(i);
auto* landmark = landmarks.add_landmark();
landmark->set_x(norm_landmark.x() * image_width);
landmark->set_y(norm_landmark.y() * image_height);
// Scale Z the same way as X (using image width).
landmark->set_z(norm_landmark.z() * image_width);
if (norm_landmark.has_visibility()) {
landmark->set_visibility(norm_landmark.visibility());
} else {
landmark->clear_visibility();
}
if (norm_landmark.has_presence()) {
landmark->set_presence(norm_landmark.presence());
} else {
landmark->clear_presence();
}
}
}
void LandmarksToNormalizedLandmarks(const LandmarkList& landmarks,
const int image_width,
const int image_height,
NormalizedLandmarkList& norm_landmarks) {
for (int i = 0; i < landmarks.landmark_size(); ++i) {
const auto& landmark = landmarks.landmark(i);
auto* norm_landmark = norm_landmarks.add_landmark();
norm_landmark->set_x(landmark.x() / image_width);
norm_landmark->set_y(landmark.y() / image_height);
// Scale Z the same way as X (using image width).
norm_landmark->set_z(landmark.z() / image_width);
if (landmark.has_visibility()) {
norm_landmark->set_visibility(landmark.visibility());
} else {
norm_landmark->clear_visibility();
}
if (landmark.has_presence()) {
norm_landmark->set_presence(landmark.presence());
} else {
norm_landmark->clear_presence();
}
}
}
float GetObjectScale(const NormalizedRect& roi, const int image_width,
const int image_height) {
const float object_width = roi.width() * image_width;
const float object_height = roi.height() * image_height;
return (object_width + object_height) / 2.0f;
}
float GetObjectScale(const Rect& roi) {
return (roi.width() + roi.height()) / 2.0f;
}
absl::StatusOr<std::unique_ptr<LandmarksFilter>> InitializeLandmarksFilter(
const LandmarksSmoothingCalculatorOptions& options) {
if (options.has_no_filter()) {
return absl::make_unique<NoFilter>();
} else if (options.has_velocity_filter()) {
return absl::make_unique<VelocityFilter>(
options.velocity_filter().window_size(),
options.velocity_filter().velocity_scale(),
options.velocity_filter().min_allowed_object_scale(),
options.velocity_filter().disable_value_scaling());
} else if (options.has_one_euro_filter()) {
return absl::make_unique<OneEuroFilterImpl>(
options.one_euro_filter().frequency(),
options.one_euro_filter().min_cutoff(),
options.one_euro_filter().beta(),
options.one_euro_filter().derivate_cutoff(),
options.one_euro_filter().min_allowed_object_scale(),
options.one_euro_filter().disable_value_scaling());
} else {
RET_CHECK_FAIL()
<< "Landmarks filter is either not specified or not supported";
}
}
absl::StatusOr<LandmarksFilter*> MultiLandmarkFilters::GetOrCreate(
const int64_t tracking_id,
const mediapipe::LandmarksSmoothingCalculatorOptions& options) {
const auto it = filters_.find(tracking_id);
if (it != filters_.end()) {
return it->second.get();
}
ASSIGN_OR_RETURN(auto landmarks_filter, InitializeLandmarksFilter(options));
filters_[tracking_id] = std::move(landmarks_filter);
return filters_[tracking_id].get();
}
void MultiLandmarkFilters::ClearUnused(
const std::vector<int64_t>& tracking_ids) {
std::vector<int64_t> unused_tracking_ids;
for (const auto& it : filters_) {
bool unused = true;
for (int64_t tracking_id : tracking_ids) {
if (tracking_id == it.first) unused = false;
}
if (unused) unused_tracking_ids.push_back(it.first);
}
for (int64_t tracking_id : unused_tracking_ids) {
filters_.erase(tracking_id);
}
}
void MultiLandmarkFilters::Clear() { filters_.clear(); }
} // namespace landmarks_smoothing
} // namespace mediapipe
@@ -0,0 +1,77 @@
// 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.
#ifndef MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_SMOOTHING_CALCULATOR_UTILS_H_
#define MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_SMOOTHING_CALCULATOR_UTILS_H_
#include "mediapipe/calculators/util/landmarks_smoothing_calculator.pb.h"
#include "mediapipe/framework/calculator_context.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
#include "mediapipe/util/filtering/one_euro_filter.h"
#include "mediapipe/util/filtering/relative_velocity_filter.h"
namespace mediapipe {
namespace landmarks_smoothing {
void NormalizedLandmarksToLandmarks(
const mediapipe::NormalizedLandmarkList& norm_landmarks,
const int image_width, const int image_height,
mediapipe::LandmarkList& landmarks);
void LandmarksToNormalizedLandmarks(
const mediapipe::LandmarkList& landmarks, const int image_width,
const int image_height, mediapipe::NormalizedLandmarkList& norm_landmarks);
float GetObjectScale(const NormalizedRect& roi, const int image_width,
const int image_height);
float GetObjectScale(const Rect& roi);
// Abstract class for various landmarks filters.
class LandmarksFilter {
public:
virtual ~LandmarksFilter() = default;
virtual absl::Status Reset() { return absl::OkStatus(); }
virtual absl::Status Apply(const mediapipe::LandmarkList& in_landmarks,
const absl::Duration& timestamp,
const absl::optional<float> object_scale_opt,
mediapipe::LandmarkList& out_landmarks) = 0;
};
absl::StatusOr<std::unique_ptr<LandmarksFilter>> InitializeLandmarksFilter(
const mediapipe::LandmarksSmoothingCalculatorOptions& options);
class MultiLandmarkFilters {
public:
virtual ~MultiLandmarkFilters() = default;
virtual absl::StatusOr<LandmarksFilter*> GetOrCreate(
const int64_t tracking_id,
const mediapipe::LandmarksSmoothingCalculatorOptions& options);
virtual void ClearUnused(const std::vector<int64_t>& tracking_ids);
virtual void Clear();
private:
std::map<int64_t, std::unique_ptr<LandmarksFilter>> filters_;
};
} // namespace landmarks_smoothing
} // namespace mediapipe
#endif // MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_SMOOTHING_CALCULATOR_UTILS_H_
@@ -0,0 +1,118 @@
/* 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.
==============================================================================*/
#include "mediapipe/calculators/util/landmarks_smoothing_calculator_utils.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/port/gmock.h"
#include "mediapipe/framework/port/gtest.h"
namespace mediapipe {
namespace landmarks_smoothing {
namespace {
TEST(LandmarksSmoothingCalculatorUtilsTest, NormalizedLandmarksToLandmarks) {
NormalizedLandmarkList norm_landmarks;
NormalizedLandmark* norm_landmark = norm_landmarks.add_landmark();
norm_landmark->set_x(0.1);
norm_landmark->set_y(0.2);
norm_landmark->set_z(0.3);
norm_landmark->set_visibility(0.4);
norm_landmark->set_presence(0.5);
LandmarkList landmarks;
NormalizedLandmarksToLandmarks(norm_landmarks, /*image_width=*/10,
/*image_height=*/10, landmarks);
EXPECT_EQ(landmarks.landmark_size(), 1);
Landmark landmark = landmarks.landmark(0);
EXPECT_NEAR(landmark.x(), 1.0, 1e-6);
EXPECT_NEAR(landmark.y(), 2.0, 1e-6);
EXPECT_NEAR(landmark.z(), 3.0, 1e-6);
EXPECT_NEAR(landmark.visibility(), 0.4, 1e-6);
EXPECT_NEAR(landmark.presence(), 0.5, 1e-6);
}
TEST(LandmarksSmoothingCalculatorUtilsTest,
NormalizedLandmarksToLandmarks_EmptyVisibilityAndPresence) {
NormalizedLandmarkList norm_landmarks;
NormalizedLandmark* norm_landmark = norm_landmarks.add_landmark();
norm_landmark->set_x(0.1);
norm_landmark->set_y(0.2);
norm_landmark->set_z(0.3);
norm_landmark->clear_visibility();
norm_landmark->clear_presence();
LandmarkList landmarks;
NormalizedLandmarksToLandmarks(norm_landmarks, /*image_width=*/10,
/*image_height=*/10, landmarks);
EXPECT_EQ(landmarks.landmark_size(), 1);
Landmark landmark = landmarks.landmark(0);
EXPECT_NEAR(landmark.x(), 1.0, 1e-6);
EXPECT_NEAR(landmark.y(), 2.0, 1e-6);
EXPECT_NEAR(landmark.z(), 3.0, 1e-6);
EXPECT_FALSE(landmark.has_visibility());
EXPECT_FALSE(landmark.has_presence());
}
TEST(LandmarksSmoothingCalculatorUtilsTest, LandmarksToNormalizedLandmarks) {
LandmarkList landmarks;
Landmark* landmark = landmarks.add_landmark();
landmark->set_x(1.0);
landmark->set_y(2.0);
landmark->set_z(3.0);
landmark->set_visibility(0.4);
landmark->set_presence(0.5);
NormalizedLandmarkList norm_landmarks;
LandmarksToNormalizedLandmarks(landmarks, /*image_width=*/10,
/*image_height=*/10, norm_landmarks);
EXPECT_EQ(norm_landmarks.landmark_size(), 1);
NormalizedLandmark norm_landmark = norm_landmarks.landmark(0);
EXPECT_NEAR(norm_landmark.x(), 0.1, 1e-6);
EXPECT_NEAR(norm_landmark.y(), 0.2, 1e-6);
EXPECT_NEAR(norm_landmark.z(), 0.3, 1e-6);
EXPECT_NEAR(norm_landmark.visibility(), 0.4, 1e-6);
EXPECT_NEAR(norm_landmark.presence(), 0.5, 1e-6);
}
TEST(LandmarksSmoothingCalculatorUtilsTest,
LandmarksToNormalizedLandmarks_EmptyVisibilityAndPresence) {
LandmarkList landmarks;
Landmark* landmark = landmarks.add_landmark();
landmark->set_x(1.0);
landmark->set_y(2.0);
landmark->set_z(3.0);
landmark->clear_visibility();
landmark->clear_presence();
NormalizedLandmarkList norm_landmarks;
LandmarksToNormalizedLandmarks(landmarks, /*image_width=*/10,
/*image_height=*/10, norm_landmarks);
EXPECT_EQ(norm_landmarks.landmark_size(), 1);
NormalizedLandmark norm_landmark = norm_landmarks.landmark(0);
EXPECT_NEAR(norm_landmark.x(), 0.1, 1e-6);
EXPECT_NEAR(norm_landmark.y(), 0.2, 1e-6);
EXPECT_NEAR(norm_landmark.z(), 0.3, 1e-6);
EXPECT_FALSE(norm_landmark.has_visibility());
EXPECT_FALSE(norm_landmark.has_presence());
}
} // namespace
} // namespace landmarks_smoothing
} // namespace mediapipe
@@ -322,27 +322,30 @@ absl::Status LandmarksToRenderDataCalculator::Process(CalculatorContext* cc) {
options_.presence_threshold(), options_.connection_color(), thickness,
/*normalized=*/false, render_data.get());
}
for (int i = 0; i < landmarks.landmark_size(); ++i) {
const Landmark& landmark = landmarks.landmark(i);
if (options_.render_landmarks()) {
for (int i = 0; i < landmarks.landmark_size(); ++i) {
const Landmark& landmark = landmarks.landmark(i);
if (!IsLandmarkVisibleAndPresent<Landmark>(
landmark, options_.utilize_visibility(),
options_.visibility_threshold(), options_.utilize_presence(),
options_.presence_threshold())) {
continue;
}
if (!IsLandmarkVisibleAndPresent<Landmark>(
landmark, options_.utilize_visibility(),
options_.visibility_threshold(), options_.utilize_presence(),
options_.presence_threshold())) {
continue;
}
auto* landmark_data_render = AddPointRenderData(
options_.landmark_color(), thickness, render_data.get());
if (visualize_depth) {
SetColorSizeValueFromZ(landmark.z(), z_min, z_max, landmark_data_render,
options_.min_depth_circle_thickness(),
options_.max_depth_circle_thickness());
auto* landmark_data_render = AddPointRenderData(
options_.landmark_color(), thickness, render_data.get());
if (visualize_depth) {
SetColorSizeValueFromZ(landmark.z(), z_min, z_max,
landmark_data_render,
options_.min_depth_circle_thickness(),
options_.max_depth_circle_thickness());
}
auto* landmark_data = landmark_data_render->mutable_point();
landmark_data->set_normalized(false);
landmark_data->set_x(landmark.x());
landmark_data->set_y(landmark.y());
}
auto* landmark_data = landmark_data_render->mutable_point();
landmark_data->set_normalized(false);
landmark_data->set_x(landmark.x());
landmark_data->set_y(landmark.y());
}
}
@@ -368,27 +371,30 @@ absl::Status LandmarksToRenderDataCalculator::Process(CalculatorContext* cc) {
options_.presence_threshold(), options_.connection_color(), thickness,
/*normalized=*/true, render_data.get());
}
for (int i = 0; i < landmarks.landmark_size(); ++i) {
const NormalizedLandmark& landmark = landmarks.landmark(i);
if (options_.render_landmarks()) {
for (int i = 0; i < landmarks.landmark_size(); ++i) {
const NormalizedLandmark& landmark = landmarks.landmark(i);
if (!IsLandmarkVisibleAndPresent<NormalizedLandmark>(
landmark, options_.utilize_visibility(),
options_.visibility_threshold(), options_.utilize_presence(),
options_.presence_threshold())) {
continue;
}
if (!IsLandmarkVisibleAndPresent<NormalizedLandmark>(
landmark, options_.utilize_visibility(),
options_.visibility_threshold(), options_.utilize_presence(),
options_.presence_threshold())) {
continue;
}
auto* landmark_data_render = AddPointRenderData(
options_.landmark_color(), thickness, render_data.get());
if (visualize_depth) {
SetColorSizeValueFromZ(landmark.z(), z_min, z_max, landmark_data_render,
options_.min_depth_circle_thickness(),
options_.max_depth_circle_thickness());
auto* landmark_data_render = AddPointRenderData(
options_.landmark_color(), thickness, render_data.get());
if (visualize_depth) {
SetColorSizeValueFromZ(landmark.z(), z_min, z_max,
landmark_data_render,
options_.min_depth_circle_thickness(),
options_.max_depth_circle_thickness());
}
auto* landmark_data = landmark_data_render->mutable_point();
landmark_data->set_normalized(true);
landmark_data->set_x(landmark.x());
landmark_data->set_y(landmark.y());
}
auto* landmark_data = landmark_data_render->mutable_point();
landmark_data->set_normalized(true);
landmark_data->set_x(landmark.x());
landmark_data->set_y(landmark.y());
}
}
@@ -32,6 +32,10 @@ message LandmarksToRenderDataCalculatorOptions {
// Color of the landmarks.
optional Color landmark_color = 2;
// Whether to render landmarks as points.
optional bool render_landmarks = 14 [default = true];
// Color of the connections.
optional Color connection_color = 3;
@@ -18,6 +18,9 @@ package mediapipe;
import "mediapipe/framework/calculator.proto";
option java_package = "com.google.mediapipe.calculator.proto";
option java_outer_classname = "LogicCalculatorOptionsProto";
message LogicCalculatorOptions {
extend CalculatorOptions {
optional LogicCalculatorOptions ext = 338731246;
@@ -0,0 +1,113 @@
// 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.
#include "mediapipe/calculators/util/multi_landmarks_smoothing_calculator.h"
#include <cstdint>
#include <memory>
#include <optional>
#include <vector>
#include "mediapipe/calculators/util/landmarks_smoothing_calculator.pb.h"
#include "mediapipe/calculators/util/landmarks_smoothing_calculator_utils.h"
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/framework/timestamp.h"
namespace mediapipe {
namespace api2 {
namespace {
using ::mediapipe::NormalizedRect;
using ::mediapipe::landmarks_smoothing::GetObjectScale;
using ::mediapipe::landmarks_smoothing::LandmarksToNormalizedLandmarks;
using ::mediapipe::landmarks_smoothing::MultiLandmarkFilters;
using ::mediapipe::landmarks_smoothing::NormalizedLandmarksToLandmarks;
} // namespace
class MultiLandmarksSmoothingCalculatorImpl
: public NodeImpl<MultiLandmarksSmoothingCalculator> {
public:
absl::Status Process(CalculatorContext* cc) override {
// Check that landmarks are not empty and reset the filter if so.
// Don't emit an empty packet for this timestamp.
if (kInNormLandmarks(cc).IsEmpty()) {
multi_filters_.Clear();
return absl::OkStatus();
}
const auto& timestamp =
absl::Microseconds(cc->InputTimestamp().Microseconds());
const auto& tracking_ids = kTrackingIds(cc).Get();
multi_filters_.ClearUnused(tracking_ids);
const auto& in_norm_landmarks_vec = kInNormLandmarks(cc).Get();
RET_CHECK_EQ(in_norm_landmarks_vec.size(), tracking_ids.size());
int image_width;
int image_height;
std::tie(image_width, image_height) = kImageSize(cc).Get();
std::optional<std::vector<NormalizedRect>> object_scale_roi_vec;
if (kObjectScaleRoi(cc).IsConnected() && !kObjectScaleRoi(cc).IsEmpty()) {
object_scale_roi_vec = kObjectScaleRoi(cc).Get();
RET_CHECK_EQ(object_scale_roi_vec.value().size(), tracking_ids.size());
}
std::vector<NormalizedLandmarkList> out_norm_landmarks_vec;
for (int i = 0; i < tracking_ids.size(); ++i) {
LandmarkList in_landmarks;
NormalizedLandmarksToLandmarks(in_norm_landmarks_vec[i], image_width,
image_height, in_landmarks);
std::optional<float> object_scale;
if (object_scale_roi_vec) {
object_scale = GetObjectScale(object_scale_roi_vec.value()[i],
image_width, image_height);
}
ASSIGN_OR_RETURN(auto* landmarks_filter,
multi_filters_.GetOrCreate(
tracking_ids[i],
cc->Options<LandmarksSmoothingCalculatorOptions>()));
LandmarkList out_landmarks;
MP_RETURN_IF_ERROR(landmarks_filter->Apply(in_landmarks, timestamp,
object_scale, out_landmarks));
NormalizedLandmarkList out_norm_landmarks;
LandmarksToNormalizedLandmarks(out_landmarks, image_width, image_height,
out_norm_landmarks);
out_norm_landmarks_vec.push_back(std::move(out_norm_landmarks));
}
kOutNormLandmarks(cc).Send(std::move(out_norm_landmarks_vec));
return absl::OkStatus();
}
private:
MultiLandmarkFilters multi_filters_;
};
MEDIAPIPE_NODE_IMPLEMENTATION(MultiLandmarksSmoothingCalculatorImpl);
} // namespace api2
} // namespace mediapipe
@@ -0,0 +1,81 @@
// 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.
#ifndef MEDIAPIPE_CALCULATORS_UTIL_MULTI_LANDMARKS_SMOOTHING_CALCULATOR_H_
#define MEDIAPIPE_CALCULATORS_UTIL_MULTI_LANDMARKS_SMOOTHING_CALCULATOR_H_
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
namespace mediapipe {
namespace api2 {
// A calculator to smooth landmarks over time.
//
// Inputs:
// NORM_LANDMARKS: A std::vector<NormalizedLandmarkList> of landmarks you want
// to smooth.
// TRACKING_IDS: A std<int64_t> vector of tracking IDs used to associate
// landmarks over time. When new ID arrives - calculator will initialize new
// filter. When tracking ID is no longer provided - calculator will forget
// smoothing state.
// IMAGE_SIZE: A std::pair<int, int> represention of image width and height.
// Required to perform all computations in absolute coordinates to avoid any
// influence of normalized values.
// OBJECT_SCALE_ROI (optional): A std::vector<NormRect> used to determine the
// object scale for some of the filters. If not provided - object scale will
// be calculated from landmarks.
//
// Outputs:
// NORM_FILTERED_LANDMARKS: A std::vector<NormalizedLandmarkList> of smoothed
// landmarks.
//
// Example config:
// node {
// calculator: "MultiLandmarksSmoothingCalculator"
// input_stream: "NORM_LANDMARKS:pose_landmarks"
// input_stream: "IMAGE_SIZE:image_size"
// input_stream: "OBJECT_SCALE_ROI:roi"
// output_stream: "NORM_FILTERED_LANDMARKS:pose_landmarks_filtered"
// options: {
// [mediapipe.LandmarksSmoothingCalculatorOptions.ext] {
// velocity_filter: {
// window_size: 5
// velocity_scale: 10.0
// }
// }
// }
// }
//
class MultiLandmarksSmoothingCalculator : public NodeIntf {
public:
static constexpr Input<std::vector<mediapipe::NormalizedLandmarkList>>
kInNormLandmarks{"NORM_LANDMARKS"};
static constexpr Input<std::vector<int64_t>> kTrackingIds{"TRACKING_IDS"};
static constexpr Input<std::pair<int, int>> kImageSize{"IMAGE_SIZE"};
static constexpr Input<std::vector<NormalizedRect>>::Optional kObjectScaleRoi{
"OBJECT_SCALE_ROI"};
static constexpr Output<std::vector<mediapipe::NormalizedLandmarkList>>
kOutNormLandmarks{"NORM_FILTERED_LANDMARKS"};
MEDIAPIPE_NODE_INTERFACE(MultiLandmarksSmoothingCalculator, kInNormLandmarks,
kTrackingIds, kImageSize, kObjectScaleRoi,
kOutNormLandmarks);
};
} // namespace api2
} // namespace mediapipe
#endif // MEDIAPIPE_CALCULATORS_UTIL_MULTI_LANDMARKS_SMOOTHING_CALCULATOR_H_
@@ -0,0 +1,100 @@
// 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.
#include "mediapipe/calculators/util/multi_world_landmarks_smoothing_calculator.h"
#include <cstdint>
#include <memory>
#include <optional>
#include <vector>
#include "mediapipe/calculators/util/landmarks_smoothing_calculator.pb.h"
#include "mediapipe/calculators/util/landmarks_smoothing_calculator_utils.h"
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/framework/timestamp.h"
namespace mediapipe {
namespace api2 {
namespace {
using ::mediapipe::Rect;
using ::mediapipe::landmarks_smoothing::GetObjectScale;
using ::mediapipe::landmarks_smoothing::MultiLandmarkFilters;
} // namespace
class MultiWorldLandmarksSmoothingCalculatorImpl
: public NodeImpl<MultiWorldLandmarksSmoothingCalculator> {
public:
absl::Status Process(CalculatorContext* cc) override {
// Check that landmarks are not empty and reset the filter if so.
// Don't emit an empty packet for this timestamp.
if (kInLandmarks(cc).IsEmpty()) {
multi_filters_.Clear();
return absl::OkStatus();
}
const auto& timestamp =
absl::Microseconds(cc->InputTimestamp().Microseconds());
const auto& tracking_ids = kTrackingIds(cc).Get();
multi_filters_.ClearUnused(tracking_ids);
const auto& in_landmarks_vec = kInLandmarks(cc).Get();
RET_CHECK_EQ(in_landmarks_vec.size(), tracking_ids.size());
std::optional<std::vector<Rect>> object_scale_roi_vec;
if (kObjectScaleRoi(cc).IsConnected() && !kObjectScaleRoi(cc).IsEmpty()) {
object_scale_roi_vec = kObjectScaleRoi(cc).Get();
RET_CHECK_EQ(object_scale_roi_vec.value().size(), tracking_ids.size());
}
std::vector<LandmarkList> out_landmarks_vec;
for (int i = 0; i < tracking_ids.size(); ++i) {
const auto& in_landmarks = in_landmarks_vec[i];
std::optional<float> object_scale;
if (object_scale_roi_vec) {
object_scale = GetObjectScale(object_scale_roi_vec.value()[i]);
}
ASSIGN_OR_RETURN(auto* landmarks_filter,
multi_filters_.GetOrCreate(
tracking_ids[i],
cc->Options<LandmarksSmoothingCalculatorOptions>()));
LandmarkList out_landmarks;
MP_RETURN_IF_ERROR(landmarks_filter->Apply(in_landmarks, timestamp,
object_scale, out_landmarks));
out_landmarks_vec.push_back(std::move(out_landmarks));
}
kOutLandmarks(cc).Send(std::move(out_landmarks_vec));
return absl::OkStatus();
}
private:
MultiLandmarkFilters multi_filters_;
};
MEDIAPIPE_NODE_IMPLEMENTATION(MultiWorldLandmarksSmoothingCalculatorImpl);
} // namespace api2
} // namespace mediapipe
@@ -0,0 +1,74 @@
// 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.
#ifndef MEDIAPIPE_CALCULATORS_UTIL_MULTI_WORLD_LANDMARKS_SMOOTHING_CALCULATOR_H_
#define MEDIAPIPE_CALCULATORS_UTIL_MULTI_WORLD_LANDMARKS_SMOOTHING_CALCULATOR_H_
#include "mediapipe/framework/api2/node.h"
#include "mediapipe/framework/formats/landmark.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
namespace mediapipe {
namespace api2 {
// A calculator to smooth landmarks over time.
//
// Inputs:
// LANDMARKS: A std::vector<LandmarkList> of landmarks you want to
// smooth.
// TRACKING_IDS: A std<int64_t> vector of tracking IDs used to associate
// landmarks over time. When new ID arrives - calculator will initialize new
// filter. When tracking ID is no longer provided - calculator will forget
// smoothing state.
// OBJECT_SCALE_ROI (optional): A std::vector<Rect> used to determine the
// object scale for some of the filters. If not provided - object scale will
// be calculated from landmarks.
//
// Outputs:
// FILTERED_LANDMARKS: A std::vector<LandmarkList> of smoothed landmarks.
//
// Example config:
// node {
// calculator: "MultiWorldLandmarksSmoothingCalculator"
// input_stream: "LANDMARKS:landmarks"
// input_stream: "OBJECT_SCALE_ROI:roi"
// output_stream: "FILTERED_LANDMARKS:landmarks_filtered"
// options: {
// [mediapipe.LandmarksSmoothingCalculatorOptions.ext] {
// velocity_filter: {
// window_size: 5
// velocity_scale: 10.0
// }
// }
// }
// }
//
class MultiWorldLandmarksSmoothingCalculator : public NodeIntf {
public:
static constexpr Input<std::vector<mediapipe::LandmarkList>> kInLandmarks{
"LANDMARKS"};
static constexpr Input<std::vector<int64_t>> kTrackingIds{"TRACKING_IDS"};
static constexpr Input<std::vector<Rect>>::Optional kObjectScaleRoi{
"OBJECT_SCALE_ROI"};
static constexpr Output<std::vector<mediapipe::LandmarkList>> kOutLandmarks{
"FILTERED_LANDMARKS"};
MEDIAPIPE_NODE_INTERFACE(MultiWorldLandmarksSmoothingCalculator, kInLandmarks,
kTrackingIds, kObjectScaleRoi, kOutLandmarks);
};
} // namespace api2
} // namespace mediapipe
#endif // MEDIAPIPE_CALCULATORS_UTIL_MULTI_WORLD_LANDMARKS_SMOOTHING_CALCULATOR_H_
@@ -124,7 +124,7 @@ absl::StatusOr<mediapipe::NormalizedLandmarkList> RefineLandmarksFromHeatMap(
int center_row = out_lms.landmark(lm_index).y() * hm_height;
// Point is outside of the image let's keep it intact.
if (center_col < 0 || center_col >= hm_width || center_row < 0 ||
center_col >= hm_height) {
center_row >= hm_height) {
continue;
}
-4
View File
@@ -130,7 +130,6 @@ cc_library(
"//mediapipe/framework/formats:video_stream_header",
"//mediapipe/framework/port:opencv_imgproc",
"//mediapipe/framework/port:opencv_video",
"//mediapipe/framework/port:ret_check",
"//mediapipe/framework/port:status",
"//mediapipe/framework/tool:status_util",
],
@@ -341,7 +340,6 @@ cc_test(
"//mediapipe/framework/port:opencv_core",
"//mediapipe/framework/port:parse_text_proto",
"//mediapipe/framework/tool:test_util",
"@com_google_absl//absl/flags:flag",
],
)
@@ -367,7 +365,6 @@ cc_test(
"//mediapipe/framework/port:opencv_video",
"//mediapipe/framework/port:parse_text_proto",
"//mediapipe/framework/tool:test_util",
"@com_google_absl//absl/flags:flag",
],
)
@@ -451,7 +448,6 @@ cc_test(
"//mediapipe/framework/tool:test_util",
"//mediapipe/util/tracking:box_tracker_cc_proto",
"//mediapipe/util/tracking:tracking_cc_proto",
"@com_google_absl//absl/flags:flag",
],
)
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

Some files were not shown because too many files have changed in this diff Show More